圖——鄰接表表示(C++代碼)
阿新 • • 發佈:2019-03-23
16px other ats 存儲 一個 不可 groups 初始 create
上學期學了數據結構,但是總是掌握不牢固,這學期的算法課給了這樣一道OJ題目
描述:
There is a group of people playing table tennis, each person can only play with the others once.
The rules of the game are as follows:
If A beats B, and B beats C, and there is no competition between A and C, then A beats C.
If A beats B, B beats C, and C beats A, then no one is champion.
Your task is to figure out whether there is a champion.
Input
Each test case contains several groups. One group begins with an integer n(n<1000), followed by n lines. Each line has a pair of names (separated by space), which means the first one beats the second one. If n is 0, the input ends.
Output
If there is a winner, print "Yes", else print "No".
示例測試集:
- 第1組
輸入:
2
qRj dIm
aTy oFu
4
qRj aTy
qRj oFu
oFu cLq
aTy qUr
0
輸出:
No Yes
這道題明顯是用圖論的知識,我的解題思路如下,通過每次輸入構建一個有向圖,然後通過判斷
1.圖中入度為0的頂點,當且僅當存在一個入度為0的頂點才可能有winner
2.圖是否有環,如果存在環,則肯定不可能有winner
3.個人認為第二點太過絕對,例如a b b c c d d a 我覺得這組數據中是有勝利者d的但是通過試驗,測試點中並沒有考慮這種情況,故我也不考慮了
具體代碼如下
#include <iostream> #include<string> #include<stack> #define MAXVERTEX 10000 //最大頂點數 using namespace std; int indegree[MAXVERTEX]; typedef string vertextype; //定義頂點的存儲類型 typedef struct ArcNode //邊表節點 { int adjvex; //鄰接點域,存儲該頂點對應的下標 struct ArcNode *next; //鏈域,指向下一個鄰接點 }ArcNode; typedef struct VertexNode //頂點表節點 { vertextype data; //存儲頂點數據的信息 ArcNode *firstarc; //邊表頭指針 }AdjList[MAXVERTEX]; typedef struct { AdjList adjlist; //定義鄰接表 int numvertex; //當前鄰接表的頂點數 int numarc; //當前鄰接表的邊數 }GraphAdjList; //判斷x是不是G中的節點 bool ExitInGraph(GraphAdjList &G, VertexNode x) { for (int i = 0; i < G.numvertex; i++) { if (G.adjlist[i].data == x.data) return true; } return false; } //把G中節點x,y連接起來 void Connect(GraphAdjList &G, VertexNode x, VertexNode y) { int xindex, yindex; for (int i = 0; i < G.numvertex; i++) { if (G.adjlist[i].data == y.data) yindex = i; if (G.adjlist[i].data == x.data) xindex = i; } ArcNode *e = new ArcNode; e->adjvex = yindex; e->next = G.adjlist[xindex].firstarc; G.adjlist[xindex].firstarc = e; } //尋找當前節點在G中的index int FindeIndex(GraphAdjList &G, VertexNode x) { int xindex; for (int i = 0; i < G.numvertex; i++) { if (G.adjlist[i].data == x.data) return i; } } //建立圖的鄰接表 void CreateAdjListGraph(GraphAdjList &G, int num) { ArcNode *e; G.numarc = num; //輸入當前圖的邊數 G.numvertex = 0; //初始圖的節點數為0 for (int i = 0, j = 0; i < G.numarc; i++) //建立頂點表,j用來表示當前頭結點的index { string a, b; cin >> a >> b; VertexNode x, y; x.data = a, y.data = b; if (ExitInGraph(G, x) && ExitInGraph(G, y)) { Connect(G, x, y); } else if (!ExitInGraph(G, x) && ExitInGraph(G, y)) { e = new ArcNode; G.adjlist[j].data = x.data; //給當前節點賦值data e->adjvex = FindeIndex(G, y); //給e賦值 e->next = NULL; G.adjlist[j].firstarc = e; j++; G.numvertex++; } else if (ExitInGraph(G, x) && !ExitInGraph(G, y)) { e = new ArcNode; G.adjlist[j].data = y.data; G.adjlist[j].firstarc = NULL; e->adjvex = j; int xindex = FindeIndex(G, x); e->next = G.adjlist[xindex].firstarc; G.adjlist[xindex].firstarc = e; j++; G.numvertex++; } else { e = new ArcNode; G.adjlist[j].data = x.data; G.adjlist[++j].data = y.data; G.adjlist[j].firstarc = NULL; e->adjvex = j; e->next = NULL; G.adjlist[j - 1].firstarc = e; G.numvertex += 2; j++; } } } void FindInDegree(GraphAdjList &g, int indegree[]) { //求每個頂點的入度 int i; ArcNode *p; for (i = 0; i<g.numvertex; i++) indegree[i] = 0; for (i = 0; i<g.numvertex; i++) { p = g.adjlist[i].firstarc; while (p) { indegree[p->adjvex]++; p = p->next; } } } bool TopologicalSort(GraphAdjList &g) //判斷圖中是否存在回路 存在 返回 true { for (int i = 0; i<g.numvertex; i++) indegree[i] = 0; int count; int k, i; ArcNode *p; stack<int>s; FindInDegree(g, indegree); //對各頂點求入度 for (i = 0; i<g.numvertex; i++) //將入度為0的頂點壓入棧 if (!indegree[i]) { s.push(i); //visited[i] = 1; } //if (s.size() != 1)return true;//不能擁有兩個入讀為0 的點 count = 0; while (!s.empty()) { i = s.top(); s.pop(); cout<<g.adjlist[i].data <<" "; //輸出拓撲排序序列 count++; for (p = g.adjlist[i].firstarc; p; p = p->next) { k = p->adjvex; //visited[k] = 1; if (!(--indegree[k])) s.push(k); } } if ((count == g.numvertex)) { return false;//這就說明沒有環 } else return true; //printf("\n該圖有回路\n"); } int main() { int n; while (cin >> n, n) { GraphAdjList G; CreateAdjListGraph(G, n); if (TopologicalSort(G)) cout << "No" << endl; else cout << "Yes" << endl; n = 0; } //system("pause"); return 0; }
代碼不完善,還請多多原諒
圖——鄰接表表示(C++代碼)