loj 1168(Tarjan应用)
来源:互联网 发布:兔子白网络 编辑:程序博客网 时间:2024/05/22 07:57
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26882
思路:一开始把题意理解错了,还以为是简单路径,然后仔细一看发现是一条路径,意思就是说从起点出发,把所有的点走一遍,于是就要考虑强连通分量,因为对于同一个强连通分量的点是相互可达的,于是我们可以先缩点,建新图,统计新图中顶点的入度与出度的关系,判断即可。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<climits> 7 #include<algorithm> 8 #include<stack> 9 #include<map> 10 #include<set> 11 #include<vector> 12 #include<queue> 13 #include<list> 14 using namespace std; 15 #define MAXN 1111 16 #define inf 1<<30 17 #define INF 1LL<<60 18 #define FILL(a,b) memset(a,b,sizeof(a)) 19 typedef long long ll; 20 typedef unsigned long long llu; 21 typedef pair<int,int>PP; 22 template<class T> inline T Get_MIN(const T &a,const T &b){ return a < b ? a : b; } 23 template<class T> inline T Get_MAX(const T &a,const T &b){ return a > b ? a : b; } 24 template<class T> inline T ABS(const T &a){ return a < 0 ? -a : a; } 25 26 int n,m,k; 27 bool vis[MAXN]; 28 vector<vector<int> >g,num; 29 map<int,int>ID; 30 31 int low[MAXN],dfn[MAXN],color[MAXN]; 32 int scc_count,cnt; 33 bool mark[MAXN]; 34 stack<int>S; 35 36 void Tarjan(int u) 37 { 38 low[u]=dfn[u]=++cnt; 39 mark[u]=true; 40 S.push(u); 41 for(int i=0;i<g[u].size();i++){ 42 int v=g[u][i]; 43 if(dfn[v]==0){ 44 Tarjan(v); 45 low[u]=Get_MIN(low[u],low[v]); 46 }else if(mark[v]){ 47 low[u]=Get_MIN(low[u],dfn[v]); 48 } 49 } 50 if(low[u]==dfn[u]){ 51 scc_count++; 52 int v; 53 do{ 54 v=S.top(); 55 S.pop(); 56 mark[v]=false; 57 color[v]=scc_count; 58 }while(u!=v); 59 } 60 } 61 62 int In_degree[MAXN],Out_degree[MAXN]; 63 void Build() 64 { 65 FILL(In_degree,0); 66 FILL(Out_degree,0); 67 for(int u=1;u<=m;u++){ 68 for(int i=0;i<g[u].size();i++){ 69 int v=g[u][i]; 70 if(color[u]!=color[v]){ 71 In_degree[color[v]]++; 72 Out_degree[color[u]]++; 73 } 74 } 75 } 76 } 77 78 79 80 int main() 81 { 82 int _case,u,v,t=1; 83 scanf("%d",&_case); 84 while(_case--){ 85 scanf("%d",&n); 86 g.clear(); 87 g.resize(1010); 88 num.clear(); 89 num.resize(1010); 90 ID.clear(); 91 FILL(vis,false); 92 m=0; 93 for(int i=1;i<=n;i++){ 94 scanf("%d",&k); 95 while(k--){ 96 scanf("%d%d",&u,&v); 97 if(!vis[u])vis[u]=true,ID[u]=++m; 98 if(!vis[v])vis[v]=true,ID[v]=++m; 99 g[ID[u]].push_back(ID[v]);100 }101 }102 FILL(dfn,0);103 FILL(mark,false);104 scc_count=cnt=0;105 for(int i=1;i<=m;i++){106 if(dfn[i]==0)Tarjan(i);107 }108 printf("Case %d: ",t++);109 if(scc_count==1){110 puts("YES");111 continue;112 }113 Build();114 if(Out_degree[color[ID[0]]]==0||In_degree[color[ID[0]]]!=0){115 puts("NO");116 continue;117 }118 int cnt1,cnt2,cnt3;119 cnt1=cnt2=cnt3=0;120 for(int i=1;i<=scc_count;i++){121 if(In_degree[i]==0&&Out_degree[i]==1)cnt1++;122 else if(In_degree[i]==1&&Out_degree[i]==0)cnt2++;123 else if(In_degree[i]==1&&Out_degree[i]==1)cnt3++;124 }125 if(cnt1==1&&cnt2==1&&cnt1+cnt2+cnt3==scc_count){126 puts("YES");127 }else128 puts("NO");129 }130 return 0;131 }
0 0
- loj 1168(Tarjan应用)
- loj 1026( tarjan + 输出割边 )
- lightoj 1168-Wishing Snake(Tarjan的应用)
- loj 1412(树上最长直径的应用)
- Tarjan 的应用
- tarjan模板及应用
- loj 1308(点双连通分量应用)
- 关于tarjan算法的应用
- uva 610(tarjan的应用)
- 总结 Tarjan的一些应用
- poj 2553 (tarjan的应用)
- tarjan在acm里的应用
- bzoj1823 tarjan算法应用-2-sats算法
- tarjan
- Tarjan
- Tarjan
- tarjan
- tarjan
- ural 1018(树形dp)
- poj 3140(树形dp)
- loj 1034(最小点基)
- poj 2486( 树形dp)
- poj 1935(树形dp)
- loj 1168(Tarjan应用)
- loj 1004(dp)
- poj 2378(树形dp)
- poj 1463(树形dp)
- loj 1011(状态压缩+记忆化搜索)
- loj 1013(LCS+记忆化搜索)
- loj 1154(最大流+枚举汇点)
- loj 1017(dp)
- loj 1018(状压dp+记忆化搜索)