您的位置:首页 > 编程语言 > Go语言

POJ2762-Going from u to v or from v to u?(Tarjan缩点,DAG判直链)

2014-08-15 13:37 316 查看
Going from u to v or from v to u?
Time Limit: 2000MSMemory Limit: 65536K
Total Submissions: 14474Accepted: 3804
DescriptionIn order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has n rooms, and one-way corridors connecting some rooms. Each time, Wind choose two rooms x and y, and ask one of their little sons go from one to the other. The son can eithergo from x to y, or from y to x. Wind promised that her tasks are all possible, but she actually doesn't know how to decide if a task is possible. To make her life easier, Jiajia decided to choose a cave in which every pair of rooms is a possible task. Givena cave, can you tell Jiajia whether Wind can randomly choose two rooms without worrying about anything?InputThe first line contains a single integer T, the number of test cases. And followed T cases.The first line for each case contains two integers n, m(0 < n < 1001,m < 6000), the number of rooms and corridors in the cave. The next m lines each contains two integers u and v, indicating that there is a corridor connecting room u and room v directly.OutputThe output should contain T lines. Write 'Yes' if the cave has the property stated above, or 'No' otherwise.Sample Input
1
3 3
1 2
2 3
3 1
Sample Output
Yes
题意:n个点,m条边,判断对于任意两个点u,v u能到v或者v能到u。
思路:Tarjan缩点后,判断一个有向无环图是否是一条直链即可,条件为:起点,终点只有一个,且起点出度为1或0
#include <iostream>#include <cstdio>#include <cstring>#include <vector>#include <string>#include <algorithm>#include <queue>#include <stack>using namespace std;const int maxn = 1000+10;const int maxe = 6000+10;struct edge{int v,nxt;}e[maxe];int head[maxn];int n,m;stack<int> S;queue<int> que;int in[maxn],out[maxn];int dfn[maxn],lown[maxn],sccno[maxn];int dfs_clk,scc_cnt,nume;void init(){dfs_clk = 0;scc_cnt = 0;nume = 1;while(!S.empty()) S.pop();while(!que.empty()) que.pop();memset(sccno,0,sizeof sccno);memset(dfn,0,sizeof dfn);memset(in,0,sizeof in);memset(out,0,sizeof out);memset(head,0,sizeof head);}void addedge(int u,int v){e[++nume].nxt = head[u];e[nume].v = v;head[u] = nume;}void Tarjan(int u){dfn[u] = lown[u] = ++dfs_clk;S.push(u);for(int i = head[u]; i ; i = e[i].nxt){int v = e[i].v;if(!dfn[v]){Tarjan(v);lown[u] = min(lown[u],lown[v]);}else if(!sccno[v]){//在栈中,能到达的祖先lown[u] = min(lown[u],dfn[v]);}}if(lown[u]==dfn[u]){scc_cnt++;while(true){int x = S.top();S.pop();sccno[x] = scc_cnt;if(x==u) break;}}}int main(){int ncase;cin >> ncase;while(ncase--){init();scanf("%d%d",&n,&m);int a,b;for(int i = 0; i < m; i++){scanf("%d%d",&a,&b);addedge(a,b);}for(int i = 1; i <= n;i++){if(!dfn[i])Tarjan(i);}for(int i = 1; i <= n; i++){int k = sccno[i];for(int j = head[i]; j; j = e[j].nxt){int d = sccno[e[j].v];if(k!=d){in[d]++;out[k]++;}}}int tr = 0,ts = 0;bool flag = true;for(int i = 1; i <= scc_cnt; i++){if(in[i]==0){tr++;if(out[i]>1){flag = false;break;}}if(out[i]==0){ts++;}}if(flag&&tr==1&&ts==1){printf("Yes\n");}else{printf("No\n");}}return 0;}
[/code]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐