话说这道题是我大前天包宿看的一道题,一看是拓扑排序,不怎么难嘛!!于是乎从10点开始做,加上我这糟烂得英语能力,看了半天才开始写 后来事实证明,我那天晚上读题还读错了,题意说是第几组后就可以排除顺序,第几组后就可以开出矛盾,我给理解成一共有几组矛盾的,晕!! 写着写着,调着调这,大半夜过去了,天快亮了,这一下子给我整不会了,越想与不对劲!!于是寡人就看一下别人的结题报告,我去,没有一个 写法和我一样的,这让老夫情何以堪!!!本来就一宿没睡了,让我再去读和我思路不一样的代码,差点没晕过去,索性睡觉去,这一晚上太憋屈了 于是乎,今天寡人6碘酒起床,上实验室把这道题再看一看,经过我的思考后,我的拓扑排序写法简直就是弱爆
void dfs(int i) { vis[i]=true; for(int j=1;j<=n;j++) { if(!vis[j]&&g[i][j]) dfs(j); } ans[ad--]=i; } void toposort() { ad=n; memset(vis,false,sizeof(vis)); for(int i=1;i<=n;i++) { if(!vis[i])//十分重要呵呵 { dfs(i); // cout<<i<<' '; // system("pause"); } } }这就是我之前的拓扑排序写法!!!也就只能过poj 2367这样的大水体吧!!!现在一想这种写法当输入关系不能连成顺序的时候就没辙了,更别说判断能否矛盾了
我说网上的写法怎么没有和我一样的呢!寡人晕!!!!!!!!!!!!!!
废话没少说,进入正题
先说思路,就是每输入一组就进行拓扑排序,根据入度数组(indegree)来判断 当indegree有两个以上值为0时,那就是当前关系不能连成顺序,当indegree没有为0
时,那就是当前关系已经连成环了,当indegree就有一个0,那就表示已经练成关系了
这道题的先后关系也很重要,我们先判断是否矛盾(我就因为这个wa了好几次),在判断能否练成顺序
#include<iostream> using namespace std; int r[30][30],n,m; char ans[30]; int indegree[30]; bool flag; int sign; int toposort() { memset(indegree,0,sizeof(indegree)); flag=true; sign=0; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) if(r[i][j]==1) indegree[j]++;//这里就是入度数组,关键所在 } int temp; for(int i=0;i<n;i++) { temp=-1; for(int k=0;k<n;k++) { if(indegree[k]==0) { if(temp==-1) temp=k; else flag=false; } } if(temp==-1) return 1; // if(flag==false) //我已开始将判断放在这里,wa了,仔细一想当一个顺序还没有完全建成的时候这个字串是可以矛盾的,如果我把判断放//在这,就是还没判断矛盾呢!直接就退出了!!!!这就是我说的顺序问题 return 3;// ans[i]=temp+'A'; indegree[temp]--; for(int j=0;j<n;j++) if(r[temp][j]==1) indegree[j]--; } ans[n]='\0'; if(flag) return 2; else return 3; } int main() { char ta,tb,tc; while(cin>>n>>m,m||n) { int sign1=0;//用来标记当判断完成后后面的读入就不用管了 flag=false; memset(r,0,sizeof(r)); for(int i=1;i<=m;i++) { cin>>ta>>tb>>tc; r[ta-'A'][tc-'A']=1; if(sign1==1) continue; int judge=toposort(); if(judge==1) { printf("Inconsistency found after %d relations.\n",i); sign1=1; //这里我已开始用sign1判断,也是wa,后来发现当这层for循环结束后还有当sign1=1的时候flag还未false,那样就会输出两种结果了 } if(judge==2) { printf("Sorted sequence determined after %d relations: ",i); printf("%s.\n",ans); sign1=1; // flag=1; } } if(!sign1&&!flag)//所以我在for循环外面再加上一个判断!sign1,就a了,哈哈哈哈 printf("Sorted sequence cannot be determined.\n"); } return 0; }