2 数据结构课程设计小组任务2:找出从指定结点出发且长度为m的所有简单路径

问题描述 :

在使用图的邻接表ADT的基础上,设计一个算法,按照深度优先搜索的思想找出从指定结点出发且长度为m的所有简单路径。并将此算法加入到邻接表ADT中,在邻接表ADT中提供一个公有的成员函数FindPath(start, m)。

提示:

(1)这个问题相当于从指定结点开始深度优先遍历,而且遍历的深度正好为m。为此,在遍历时需要记住遍历的深度,当深度达到m时,就不需要递归了。此时需要输出这条路径,因此在遍历的过程中还需要记住整条路径。

(2)由于深度优先遍历是用递归实现的,所以FindPath函数最好也设计两个。一个是共有的FindPath函数,供用户使用(外壳);另一个是私有的FindPath函数,实现递归的遍历。公有的FingPath函数调用私有的FindPath函数找出这些路径。

(3)在调用递归的FindPath函数前,外壳函数还需要做一些辅助工作:

1)要找的是长度为m的简单路径,因此路径上不能有相同的结点,于是定义了一个数组visited记录结点是否在路径上。

2)当路径长度等于m时要输出这条路径,于是定义了一个数组stack保存这条路径。每访问一个结点,都要把结点记录在stack中。

3)递归的FindPath函数有6个参数。第1个参数是遍历的起点的序号;第2个参数是要求的路径长度;第3个参数是符合要求的路径数目;第4个参数是当前路径中的结点数,当前路径的长度是结点数减1;第5个参数是visited数组,记录结点是否在路径上;第6个参数是一个用于记录路径上结点序号的数组,作用和栈类似。

4)调用FindPath函数时要指出从哪一个结点出发,而递归的FingPath函数的参数是起点的序号。递归的FindPath函数首先将起点放入这条路径,并标记这个结点已被访问,然后判断路径长度是否是m。如果长度已达到m,则输出这条路径,并将最后一个结点从路径上删除,返回上一层调用,检查是否还有其它的途径;否则逐个检查起点的后继结点。如果该后继结点没有被访问过,则对该结点调用递归的FindPath函数继续寻找。在所有的后继都检查后,表示这条路径处理完毕。将起始结点从这条路径上删除,返回上一层调用。

参考函数原型:

(1)//找出从指定结点出发且长度为m的所有简单路径(外壳部分)

template<class TypeOfVer, class TypeOfEdge>

void adjlist_graph<TypeOfVer, TypeOfEdge>::FindPath(int start, int m);

(2)//找出从指定结点出发且长度为m的所有简单路径(递归部分)

template<class TypeOfVer, class TypeOfEdge>

void adjlist_graph<TypeOfVer, TypeOfEdge>::FindPath(int start, int m, int &count, int top, int visited[], int stack[]);

输入说明 :

第一行:图的类型

第二行:结点数

第三行:结点集

第四行:边数

第五行:边集

第六行:起点start

第七行:路径长度m

输出说明 :

第一行:顶点集

第二行:邻接表

空行

如无符合要求的路径:输出 0

否则: 路径输出(一条路径占一行)

       路径数目

输入范例 :

DG
8
1 2 3 4 5 6 7 8
8
0 1
0 2
1 3
1 4
2 5
2 6
3 7
4 7
0
2
输出范例 :

1 2 3 4 5 6 7 8
1->2->1
2->4->3
3->6->5
4->7
5->7
6
7
8

1->3->7
1->3->6
1->2->5
1->2->4
4

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

/* 边表的结点定义 */
template<class TypeOfEdge>
struct edgeNode
{
    int data;
    TypeOfEdge weight;
    edgeNode<TypeOfEdge>* next = NULL;
    edgeNode(int d = 0, edgeNode<TypeOfEdge>* ptr = NULL) //构造函数,用于构造其他结点(无权图) 
    {
        next = ptr;
        data = d;
        weight = 0;
    }
    edgeNode(int& d, TypeOfEdge& w, edgeNode<TypeOfEdge>* ptr = NULL) //构造函数,用于构造其他结点(带权图) 
    {
        next = ptr;
        data = d;
        weight = w;
    }
    edgeNode(edgeNode<TypeOfEdge>& temp)
    {
        data = temp.data;
        weight = temp.weight;
        next = NULL;
    }
    int getData() { return data; }  //取得结点的序号(顶点集) 
    TypeOfEdge getWeight() { return weight; }  //取得边集中对应边的权值 
    void SetLink(edgeNode<TypeOfEdge>* link) { next = link; }  //修改结点的next域 
    void SetData(int value) { data = value; }   //修改结点的序号(顶点集) 
    void SetWeight(TypeOfEdge value) { weight = value; }   //修改边集中对应边的权值   
};
template<class TypeOfVer, class TypeOfEdge>
struct verNode
{
    TypeOfVer ver;
    edgeNode<TypeOfEdge>* head;
    verNode(TypeOfVer data)
    {
        ver = data;
        head = new edgeNode<TypeOfEdge>;
    }
    verNode(edgeNode<TypeOfEdge>* h = new edgeNode<TypeOfEdge>) { head = h; }
    TypeOfVer getVer() { return ver; }  //取得结点值(顶点集) 
    edgeNode<TypeOfEdge> getHead() { return head; }  //取得对应的边表的头指针 
    void setVer(TypeOfVer value) { ver = value; }  //设置结点值(顶点集) 
    void setHead(edgeNode<TypeOfEdge> value) { head = value; }  //设置对应的边表的头指针
};

//图的邻接表类
template <class TypeOfVer, class TypeOfEdge>
class adjlist_graph {
private:
    int Vers = 0;           //顶点数 
    int Edges = 0;          //边数 
    vector<verNode<TypeOfVer, TypeOfEdge>> verList;//有头节点
    string GraphKind;     //图的种类标志 
    bool Delete_Edge(int u, int v)
    {
        if (u >= Vers || v >= Vers)return false;
        edgeNode<TypeOfEdge>* p, * q;
        for (p = verList[u].head, q = p->next;q != NULL;p = q, q = q->next)
        {
            if (q->data == v)
            {
                p->next = q->next;
                delete q;
                q = p;
                break;
            }
        }
        if (q == NULL)return false;
        return true;
    }
    void DFS(int u, int& num, vector<bool>& visited) //DFS遍历(递归部分)
    {
        if (num != Vers)cout << "->";
        cout << verList[u].ver;
        if (num == 0)return;
        visited[u] = 1;
        num--;
        if (num == 0)return;
        int v, w;
        GetFirstAdjVex(u, v);
        while (v != -1)
        {
            if (visited[v])
            {
                GetNextAdjVex(u, v, w);
                v = w;
            }
            else DFS(v, num, visited);
        }
    }
    bool CheckRoute(int u, int targe, vector<bool>& visited)//检查两个结点之间是否有路径存在(递归部分,私有成员函数) 
    {
        visited[u] = 1;
        if (visited[targe])return true;
        int v, w;
        GetFirstAdjVex(u, v);
        while (v != -1)
        {
            if (visited[v])
            {
                GetNextAdjVex(u, v, w);
                v = w;
            }
            else CheckRoute(v, targe, visited);
        }
        if (visited[targe])return true;
        else return false;
    }
public:
    //构造函数构造一个只有结点没有边的图。 
    adjlist_graph(string& kd, int vSize, vector<TypeOfVer>& d)
    {
        GraphKind = kd;
        Vers = vSize;
        verList.resize(Vers);
        for (int i = 0;i < Vers;i++)
        {
            verList[i].ver = d[i];
        }
    }
    ////构造函数构造一个无权图。5个参数的含义:图的类型、结点数、边数、结点集和边集 
    adjlist_graph(string& kd, int vSize, int eSize, vector<TypeOfVer>& d, vector<vector<int>>& e)
    {
        GraphKind = kd;
        Vers = vSize;
        Edges = eSize;
        verList.resize(Vers);
        for (int i = 0;i < Vers;i++)
        {
            verList[i].ver = d[i];
        }
        int count = 0;
        for (int i = 0;i < Vers;i++)
        {
            edgeNode<TypeOfEdge>* p, * q;
            for (int j = 0;j < Vers;j++)
            {
                if (e[i][j] == 0)continue;
                p = new edgeNode<TypeOfEdge>;
                p->data = j;
                p->weight = 1;
                p->next = verList[i].head->next;
                verList[i].head->next = p;
                if (GraphKind == "UDG")
                {
                    q = new edgeNode<TypeOfEdge>;
                    q->data = i;
                    q->weight = 1;
                    q->next = verList[j].head->next;
                    verList[j].head->next = q;
                }
            }
        }
    }
    //构造函数构造一个有权图。
    adjlist_graph(string& kd, int vSize, int eSize, vector<TypeOfVer>& d, vector<vector<int>>& e, vector<TypeOfEdge> w)
    {
        GraphKind = kd;
        Vers = vSize;
        Edges = eSize;
        verList.resize(Vers);
        for (int i = 0;i < Vers;i++)
        {
            verList[i].ver = d[i];
        }
        int count = 0;
        for (int i = 0;i < Vers;i++)
        {
            edgeNode<TypeOfEdge>* p, * q;
            for (int j = 0;j < Vers;j++)
            {
                if (e[i][j] != 0)
                {
                    p = new edgeNode<TypeOfEdge>;
                    p->data = j;
                    p->weight = w[count++];
                    p->next = verList[i].head->next;
                    verList[i].head->next = p;
                    if (GraphKind == "UDN")
                    {
                        q = new edgeNode<TypeOfEdge>;
                        q->data = i;
                        q->weight = p->weight;
                        q->next = verList[j].head->next;
                        verList[j].head->next = q;
                    }
                }
            }
        }
    }
    ~adjlist_graph() //析构函数
    {
        edgeNode<TypeOfEdge>* p, * q;
        for (int i = 0;i < Vers;i++)
        {
            for (p = q = verList[i].head;q != NULL;)
            {
                q = q->next;
                delete p;
                p = q;
            }
            delete p;
        }
    }

    bool PrintGraphKind()
    {
        if (Vers == 0)return false;
        cout << GraphKind << endl;
        return true;
    }
    bool PrintVer()  //输出顶点集 
    {
        if (Vers == 0)return false;
        for (int i = 0;i < Vers - 1;i++)
            cout << verList[i].ver << " ";
        cout << verList[Vers - 1].ver << endl;
        return true;
    }
    bool PrintVers()
    {
        if (Vers == 0)return false;
        cout << Vers << endl;
        return true;
    }
    bool PrintEdges()
    {
        if (Vers == 0)return false;
        cout << Edges << endl;
        return true;
    }
    bool PrintAdjList()  //输出邻接矩阵 
    {
        if (Vers == 0)return false;
        if (GraphKind == "DG" || GraphKind == "UDG")
            for (int i = 0;i < Vers;i++)
            {
                cout << verList[i].ver;
                edgeNode<TypeOfEdge>* p;
                for (p = verList[i].head->next;p != NULL;p = p->next)
                {
                    cout << "->" << p->data;
                }
                cout << endl;
            }
        else for (int i = 0;i < Vers;i++)
        {
            cout << verList[i].ver;
            edgeNode<TypeOfEdge>* p;
            for (p = verList[i].head->next;p != NULL;p = p->next)
            {
                cout << "->" << p->data << "(" << p->weight << ")";
            }
            cout << endl;
        }
        return true;
    }

    bool GraphisEmpty() { return Vers == 0; }  //判断图空否
    string GetGraphKind() { return GraphKind; }
    int GetVerNum() { return Vers; }    //取得当前顶点数 
    int GetEdgeNum() { return Edges; }  //取得当前边数 
    bool GetWeight(int u, int v, TypeOfEdge& w)//对于有权图,取两端点为v1和v2的边上的权值。获取成功,返回true;否则,返回false 
    {
        if (u >= Vers || v >= Vers)return false;
        edgeNode<TypeOfEdge>* p = verList[u].head->next;
        while (p)
        {
            if (p->data == v)
            {
                w = p->weight;
                return true;
            }
            p = p->next;
        }
        return false;
    }
    int Get_Degree(int u)//求指定顶点的(出)度(无向图/网:度; 有向图/网:出度 ) 
    {
        if (u >= Vers)return -1;
        edgeNode<TypeOfEdge>* p;
        int count = 0;
        for (p = verList[u].head->next;p != NULL;p = p->next)
            count++;
        return count;
    }
    int Get_InDegree(int u)//求有向图指定顶点的入度 
    {
        if (GraphKind == "UDG" || GraphKind == "UDN")return -1;
        if (u >= Vers)return -1;
        int count = 0;
        for (int i = 0;i < Vers;i++)
        {
            if (i == u)continue;
            edgeNode<TypeOfEdge>* p;
            for (p = verList[i].head->next;p != NULL;p = p->next)
                if (p->data == u)count++;
        }
        return count;
    }

    bool GetVer(int u, TypeOfVer& data) //取得G中指定顶点的值 
    {
        if (u >= Vers)return false;
        data = verList[u].ver;
        return true;
    }
    int GetFirstAdjVex(int u, int& v) //返回G中指定顶点u的第一个邻接顶点的位序(顶点集)。若顶点在G中没有邻接顶点,则返回-1
    {
        v = -1;
        if (u >= Vers)return v;
        if (verList[u].head->next != NULL)
        {
            v = verList[u].head->next->data;
        }
        return v;
    }
    int GetNextAdjVex(int u, int v, int& w) //返回G中指定顶点u的下一个邻接顶点(相对于v)的位序(顶点集)。若顶点在G中没有邻接顶点,则返回false
    {
        w = -1;
        if (u >= Vers)return w;
        edgeNode<TypeOfEdge>* p;
        for (p = verList[u].head->next;p != NULL;p = p->next)
        {
            if (p->data == v)
            {
                if (p->next != NULL)
                    w = p->next->data;
                return w;
            }
        }
        return w;
    }
    bool PutVer(int u, TypeOfVer data) //对G中指定顶点赋值 
    {
        if (u >= Vers)return false;
        verList[u].ver = data;
        return true;
    }
    bool InsertVer(TypeOfVer& data) //往G中添加一个顶点 
    {
        verList.push_back(verNode<TypeOfVer, TypeOfEdge>(data));
        Vers++;
        return true;
    }
    int LocateVer(TypeOfVer data) //返回G中指定顶点的位置 
    {
        for (int i = 0;i < Vers;i++)
        {
            if (verList[i].ver == data)return i;
        }
        return -1;
    }
    bool ExistEdge(int u, int v)
    {
        if (u >= Vers || v >= Vers)return false;
        edgeNode<TypeOfEdge>* p = verList[u].head->next;
        while (p)
        {
            if (p->data == v)return true;
            p = p->next;
        }
        return false;
    }
    bool Insert_Edge(int u, int v) //无权图插入一条边
    {
        if (u == v)return false;
        if (u >= Vers || v >= Vers || u < 0 || v < 0)return false;
        edgeNode<TypeOfEdge>* p, * q, * r;
        for (q = verList[u].head, r = q->next;r != NULL;q = r, r = r->next)
        {
            if (r->data == v)return false;
        }
        p = new edgeNode<TypeOfEdge>;
        p->data = v;
        p->weight = 1;
        p->next = verList[u].head->next;
        verList[u].head->next = p;
        if (GraphKind == "UDG" || GraphKind == "UDN")
        {
            p = new edgeNode<TypeOfEdge>;
            p->data = u;
            p->weight = 1;
            p->next = verList[v].head->next;
            verList[v].head->next = p;
        }
        Edges++;
        return true;
    }
    bool Insert_Edge(int u, int v, TypeOfEdge w) //有权图插入一条边
    {
        if (u == v)return false;
        if (u >= Vers || v >= Vers || u < 0 || v < 0)return false;
        edgeNode<TypeOfEdge>* p, * q, * r;
        for (q = verList[u].head, r = q->next;r != NULL;q = r, r = r->next)
        {
            if (r->data == v)return false;
        }
        p = new edgeNode<TypeOfEdge>;
        p->data = v;
        p->weight = w;
        p->next = verList[u].head->next;
        verList[u].head->next = p;
        if (GraphKind == "UDG" || GraphKind == "UDN")
        {
            p = new edgeNode<TypeOfEdge>;
            p->data = u;
            p->weight = w;
            p->next = verList[v].head->next;
            verList[v].head->next = p;
        }
        Edges++;
        return true;
    }
    bool DeleteVer(TypeOfVer& data) //往G中删除一个顶点 
    {
        int n = LocateVer(data);
        if (n != -1)
        {
            Edges++;
            edgeNode<TypeOfEdge>* p, * q;
            for (p = q = verList[n].head;q != NULL;)
            {
                Edges--;
                q = q->next;
                delete p;
                p = q;
            }
            delete p;
            verList.erase(verList.begin() + n);
        }
        else return false;
        Vers--;
        for (int i = 0;i < Vers;i++)
        {
            edgeNode<TypeOfEdge>* p, * q;
            for (p = verList[i].head, q = p->next;q != NULL;p = q, q = q->next)
            {
                if (q->data == n)
                {
                    if (GraphKind != "UDG" && GraphKind != "UDN")
                        Edges--;
                    p->next = q->next;
                    delete q;
                    q = p;
                    continue;
                }
                if (q->data > n)
                    q->data--;
            }
        }
        return true;
    }
    bool DeleteVer(int n) //往G中删除一个顶点 
    {
        if (n < 0 || n >= Vers)return false;
        edgeNode<TypeOfEdge>* p, * q;
        Edges++;
        for (p = q = verList[n].head;q != NULL;)
        {
            Edges--;
            q = q->next;
            delete p;
            p = q;
        }
        delete p;
        verList.erase(verList.begin() + n);
        Vers--;
        for (int i = 0;i < Vers;i++)
        {
            edgeNode<TypeOfEdge>* p, * q;
            for (p = verList[i].head, q = p->next;q != NULL;p = q, q = q->next)
            {
                if (q->data == n)
                {
                    if (GraphKind != "UDG" && GraphKind != "UDN")
                        Edges--;
                    p->next = q->next;
                    delete q;
                    q = p;
                    continue;
                }
                if (q->data > n)
                    q->data--;
            }
        }
        return true;
    }
    bool DeleteEdge(int u, int v) //删除边 (外壳:有向(删除1条边), 无向(删除2条边))
    {
        if (!Delete_Edge(u, v))return false;
        if (GraphKind == "UDG" || GraphKind == "UDN")
            Delete_Edge(v, u);
        Edges--;
        return true;
    }
    void DFS_Traverse(int u) //DFS遍历(外壳部分)
    {
        if (u >= Vers || u < 0)return;
        vector<bool> visited(Vers, false);
        int num = Vers;
        DFS(u, num, visited);
    }
    void BFS_Traverse(int u) //BFS遍历
    {
        queue<int>q;
        vector<int>visit(Vers, false);
        q.push(u);
        int v, w;
        bool first = true;
        visit[u] = 1;
        while (!q.empty())
        {
            if (!first)cout << "->";
            first = false;
            u = q.front();
            cout << verList[u].ver;
            q.pop();
            GetFirstAdjVex(u, v);
            while (v != -1)
            {
                if (!visit[v])
                {
                    q.push(v);
                    visit[v] = 1;
                }
                GetNextAdjVex(u, v, w);
                v = w;
            }
        }
    }
    bool CheckRoute(int u, int v)//检查两个结点之间是否有路径存在(外壳部分,公有成员函数)  
    {
        if (u >= Vers || v >= Vers)return false;
        vector<bool>visit(Vers);
        return CheckRoute(u, v, visit);
    }

    void FindPath(int start, int m)    //找出从指定结点出发且长度为m的所有简单路径(外壳部分)
    {
        vector<int> visited(Vers, 0);
        vector<int> stack(m + 1);
        stack[0] = start;
        int count = 0;
        visited[start] = 1;
        FindPath(start, m, count, 0, visited, stack);
        cout << count << endl;
    }
    void FindPath(int start, int m, int& count, int top, vector<int>& visited, vector<int>& stack)    //找出从指定结点出发且长度为m的所有简单路径(递归部分)
    {
        if (top == m)
        {
            for (int i = 0;i < m;i++)
                cout << verList[stack[i]].ver << "->";
            cout << verList[stack[m]].ver << endl;
            count++;
            return;
        }
        int u, v, w;
        u = start;
        GetFirstAdjVex(u, v);
        while (v != -1)
        {
            if (!visited[v])
            {
                visited[v] = 1;
                stack[top + 1] = v;
                FindPath(v, m, count, top + 1, visited, stack);
                stack[top + 1] = -1;
                visited[v] = 0;
            }
            GetNextAdjVex(u, v, w);
            v = w;
        }
    }
};

template <class TypeOfVer>
void input(int& vSize, int& eSize, vector<TypeOfVer>& d, vector<vector<int>>& e)
{
    cin >> vSize;
    d.resize(vSize);
    for (int i = 0;i < vSize;i++)
    {
        cin >> d[i];
    }
    cin >> eSize;
    e.resize(vSize);
    for (int i = 0;i < vSize;i++)
        e[i].resize(vSize);
    int a, b;
    for (int i = 0;i < eSize;i++)
    {
        cin >> a >> b;
        e[a][b] = 1;
    }
}

template <class TypeOfVer, class TypeOfEdge>
void input(int& vSize, int& eSize, vector<TypeOfVer>& d, vector<vector<int>>& e, vector<TypeOfEdge>& w)
{
    cin >> vSize;
    d.resize(vSize);
    for (int i = 0;i < vSize;i++)
    {
        cin >> d[i];
    }
    cin >> eSize;
    e.resize(vSize);
    for (int i = 0;i < vSize;i++)
        e[i].resize(vSize);
    int a, b;
    for (int i = 0;i < eSize;i++)
    {
        cin >> a >> b;
        e[a][b] = 1;
    }
    w.resize(eSize);
    for (int i = 0;i < eSize;i++)
        cin >> w[i];
}

template <class TypeOfVer, class TypeOfEdge>
void run(adjlist_graph<TypeOfVer, TypeOfEdge>& list)
{
    int start, m;
    cin >> start >> m;
    list.PrintVer();
    list.PrintAdjList();
    cout << endl;
    list.FindPath(start, m);
}

int main()
{
    typedef string TypeOfVer;
    typedef int TypeOfEdge;
    int vSize = 0, eSize = 0;
    vector<vector<int>>e;
    string str;
    vector<TypeOfVer> d;
    vector<TypeOfEdge>w;
    cin >> str;
    if (str == "DG" || str == "UDG")
    {
        input(vSize, eSize, d, e);//无权图的构造
        adjlist_graph<TypeOfVer, TypeOfEdge> list(str, vSize, eSize, d, e);
        run(list);
    }
    else
    {
        input(vSize, eSize, d, e, w);//有权图的构造
        adjlist_graph<TypeOfVer, TypeOfEdge> list(str, vSize, eSize, d, e, w);
        run(list);
    }
    return 0;
}

OJ测试用例
``
Ex1:

DG
8
1 2 3 4 5 6 7 8
8
0 1
0 2
1 3
1 4
2 5
2 6
3 7
4 7
0
2

Ans1:

1 2 3 4 5 6 7 8
1->2->1
2->4->3
3->6->5
4->7
5->7
6
7
8

1->3->7
1->3->6
1->2->5
1->2->4
4

Ex2:

DG
9
1 2 3 4 5 6 7 8 9
11
0 1
0 2
0 3
1 4
2 4
3 5
4 6
4 7
5 7
6 8
7 8
0
3

Ans2:

1 2 3 4 5 6 7 8 9
1->3->2->1
2->4
3->4
4->5
5->7->6
6->7
7->8
8->8
9

1->4->6->8
1->3->5->8
1->3->5->7
1->2->5->8
1->2->5->7
5

Ex3:

DG
8
1 2 3 4 5 6 7 8
8
0 1
0 2
1 3
1 4
2 5
2 6
3 7
4 7
10
2

Ans3:

49 32 50 32 51 32 52 32 53 32 54 32 55 32 56 10
49 45 62 50 45 62 49 10
50 45 62 52 45 62 51 10
51 45 62 54 45 62 53 10
52 45 62 55 10
53 45 62 55 10
54 10
55 10
56 10
10
48

Ex4:

DG
8
1 2 3 4 5 6 7 8
8
0 1
0 2
1 3
1 4
2 5
2 6
3 7
4 7
0
20

Ans4:

1 2 3 4 5 6 7 8
1->2->1
2->4->3
3->6->5
4->7
5->7
6
7
8

0


微信号公众号搜索:澜莲小哥

个人博客:[澜莲的博客](http://124.223.175.42/)

力扣:https://leetcode-cn.com/u/g-l-/

微博:澜澜沧海水
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容