题意:
题目给出一张图,问任意两点能否有一天路径连接。
题解:
强连通分量,然后缩点,只要形成一条链或者一个环就满足条件!虽然说重边不影响Tarjan的正确性,但是重边会影响度数的统计,因此一直wa,就是错在把重边重复的统计进入度数,这样判断就不准确了。
#include<iostream> #include<math.h> #include<stdio.h> #include<algorithm> #include<string.h> #include<vector> #include<queue> #include<map> #include<set> #define B(x) (1<<(x)) using namespace std; typedef long long ll; void cmax(int& a,int b){ if(b>a)a=b; } void cmin(int& a,int b){ if(b<a)a=b; } void cmax(ll& a,ll b){ if(b>a)a=b; } void cmin(ll& a,ll b){ if(b<a)a=b; } void add(int& a,int b,int mod){ a=(a+b)%mod; } void add(ll& a,ll b,ll mod){ a=(a+b)%mod; } const int oo=0x3f3f3f3f; const int MOD=2012; const int maxn=2101; const int maxm=11001; struct EDGE{ int v,next; }E[maxm<<1]; int head[maxn],tol; int low[maxn],dfn[maxn],vis[maxn],Stack[maxn],id[maxn]; int ind[maxn],oud[maxn]; int g_cnt,ID,top; int g[maxn][maxn]; void Init(){ memset(head,-1,sizeof head); tol=0; memset(low,0,sizeof low); memset(dfn,0,sizeof dfn); memset(vis,0,sizeof vis); memset(g,0,sizeof g); g_cnt=ID=top=0; } void add_edge(int u,int v){ E[tol].v=v; E[tol].next=head[u]; head[u]=tol++; } void Tarjan(int u){ dfn[u]=low[u]=++g_cnt; Stack[++top]=u; vis[u]=1; int v; for(int i=head[u];i!=-1;i=E[i].next){ v=E[i].v; if(!dfn[v]){ Tarjan(v); if(low[v]<low[u]) low[u]=low[v]; }else if(vis[v]&&dfn[v]<low[u]) low[u]=dfn[v]; } if(dfn[u]==low[u]){ ID++; do{ v=Stack[top--]; vis[v]=0; id[v]=ID; }while(u!=v); } } void gao(int n){ for(int i=1;i<=n;i++) if(!dfn[i]) Tarjan(i); if(ID==1){ puts("Kalimdor is just ahead"); return ; } memset(ind,0,sizeof ind); memset(oud,0,sizeof oud); int a,b; for(int u=1;u<=n;u++){ for(int i=head[u];i!=-1;i=E[i].next){ int v=E[i].v; a=id[u]; b=id[v]; if(a!=b){ oud[a]++; ind[b]++; } } } int cnt=0; int in=0,ou=0; for(int i=1;i<=ID;i++){ if(ind[i]==0&&oud[i]==1)in++; if(oud[i]==0&&ind[i]==1)ou++; if(ind[i]==1&&oud[i]==1)cnt++; } if(cnt==ID-2&&in==1&&ou==1) puts("Kalimdor is just ahead"); else puts("The Burning Shadow consume us all"); } int main(){ //freopen("E:\\read.txt","r",stdin); int T,n,m,u,v,cas=1; scanf("%d",&T); while(T--){ Init(); scanf("%d %d",&n,&m); for(int i=1;i<=m;i++){ scanf("%d %d",&u,&v); g[u][v]=1; } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(g[i][j]) add_edge(i,j); printf("Case %d: ",cas++); gao(n); } return 0; }