4 3 1 2 2 3 4 3
1 2 4 3
这是一道典型的拓扑排序的题目,相关详解我推荐大家来这里看:http://www.cnblogs.com/skywang12345/p/3711489.html#anchor1
首先这位博主写的比较详细,另外,相关思路我的代码是参考大牛代码和博主思维写的(相似).这里贴上两版AC代码
在详解这个题目之前,我们先来引入一个概念:度。这里我暂时没有找到相关资料表示拓扑排序中的度的概念,所以这里口述。
数学领域相关概念有之:全序,表示两者有一方依赖另一方,或者是一方决定另一方,反正就是有明确的关系。这个题目明确有样例输入(1,2)(2,3)(4,3)分别表示每一次比赛的胜败情况,也就是说满足全序的条件,一方打败了另一方。
我们了解了全序条件的时候 ,我们能够画出相应的关系图
这时候,被指向一次,度+1.相对的,各个节点相对应的度的情况是很好判定的:
点: 1 2 3 4
度: 0 1 2 0
然后我们就要应用大牛博客中的相关内容了:http://www.cnblogs.com/skywang12345/p/3711489.html#anchor1
首先我们初始化:
memset(a,0,sizeof(a));//a是二维数组,表示图。 memset(degree,0,sizeof(degree));//度 memset(output,0,sizeof(output));//答案数组 for(int i=0;i<m;i++) { int x,y; scanf("%d%d",&x,&y); if(a[x][y]==0)//首先这里要强调,避免重边。(重边算一边) { a[x][y]++;//表示xy有全序关系 degree[y]++;//度相对+1 <span style="white-space:pre"> </span> } <span style="white-space:pre"> </span>}然后我们进入代码核心部分:
int cont=0; while(true) { int j=1;//每一次都从1号点开始找 if(degree[j]!=0) { while(true) { j++; if(degree[j]==0)break; if(j>n)break; } } degree[j]=-1;//找到度为0的点然后标记上这个点已经去掉了。 //printf("%d\n",j); output[cont]=j;//进入答案数组 cont++; if(cont==n)break; for(int i=1;i<=n;i++) { if(a[j][i]>0)//找到和度为0相关的边 { degree[i]--;//去边的同时要减度 a[j][i]=-1;//并且去掉边 } } }然后是我的完整ac代码:
#include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> using namespace std; int a[502][502]; int degree[502]; int output[502]; int main() { int n,m; while(~scanf("%d%d",&n,&m)) { memset(a,0,sizeof(a)); memset(degree,0,sizeof(degree)); memset(output,0,sizeof(output)); for(int i=0;i<m;i++) { int x,y; scanf("%d%d",&x,&y); if(a[x][y]==0) { a[x][y]++; degree[y]++; } } int cont=0; while(true) { int j=1; if(degree[j]!=0) { while(true) { j++; if(degree[j]==0)break; if(j>n)break; } } degree[j]=-1; //printf("%d\n",j); output[cont]=j; cont++; if(cont==n)break; for(int i=1;i<=n;i++) { if(a[j][i]>0) { degree[i]--; a[j][i]=-1; } } } for(int i=0;i<cont-1;i++) { printf("%d ",output[i]); } printf("%d\n",output[cont-1]); } }
#include<stdio.h> #include<string.h> #include<queue> using namespace std; struct edge_node { int to; int next; }; edge_node edge[10000]; int head[10000]; int indegree[10000]; int ans[10000]; int count_ans; class compare { public: bool operator()(int x,int y) { return x>y; } }; int main() { int n,m; while(scanf("%d%d",&n,&m)!=EOF) { memset(head,-1,sizeof(head)); memset(indegree,0,sizeof(indegree)); int x,y; for(int i=1; i<=m; i++) { scanf("%d%d",&x,&y); edge[i].to=y; edge[i].next=head[x]; head[x]=i; indegree[y]++; } priority_queue<int,vector<int>,compare>q; for(int i=1;i<=n;i++) { if(indegree[i]==0) { q.push(i); } } count_ans=0; while(!q.empty()) { int temp=q.top(); q.pop(); ans[count_ans++]=temp; for(int i=head[temp];i!=-1;i=edge[i].next) { indegree[edge[i].to]--; if(indegree[edge[i].to]==0) { q.push(edge[i].to); } } } for(int i=0;i<count_ans;i++) { if(i!=0) { printf(" %d",ans[i]); } else { printf("%d",ans[i]); } } printf("\n"); } return 0; }