https://neooj.com:8081/oldoj/problem.php?id=1588
神奇。。。
tarjan 水題
WA 一次
第一次:
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
int n,m;
int to[10004],next[10004],head[1003],cnt;
void add(int x,int y){to[++cnt]=y;next[cnt]=head[x];head[x]=cnt;}
int min(int x,int y){return x<y?x:y;}
int z[1003],inz[1003],top;
int v[1003],deep[1003],low[1003],tot;
int f[1003][1003],ans;
int belong[1003];
int frudu[1003];
void tarjan(int x)
{
z[++top]=x;inz[x]=1;v[x]=1;
deep[x]=low[x]=++tot;
for(int i=head[x];i;i=next[i])
{
if(v[to[i]]==0) tarjan(to[i]),low[x]=min(low[x],low[to[i]]);
else if(inz[to[i]]==1) low[x]=min(low[x],deep[to[i]]);
}
if(deep[x]==low[x])
{
ans++;
int t;
do
{
t=z[top--];inz[t]=0;
f[ans][++f[ans][0]]=t;
belong[t]=ans;
}while(t!=x);
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
}
for(int i=1;i<=n;i++)
{
if(!v[i])
{
tarjan(i);
}
}
int love=0;
for(int i=1;i<=ans;i++)
{
if(f[i][0]!=1)love++;
}
printf("%d\n",love);
for(int i=1;i<=n;i++)
{
for(int j=head[i];j;j=next[j])
{
if(belong[i]!=belong[to[j]])
{
frudu[belong[to[j]]]++;
}
}
}
int temp=0;
for(int i=1;i<=ans;i++)
{
if(frudu[i]==ans-1&&f[i][0]!=1)
{
temp=1;
int x=f[i][0];
sort(f[i]+1,f[i]+x+1);
for(int j=1;j<=f[i][0];j++)
{
printf("%d ",f[i][j]);
}
printf("\n");
}
}
if(temp==0)
{
printf("-1\n");
}
return 0;
}
tarjan 後 縮點 計算入度,若 入度=點數-1 則爲所求。
明顯錯誤!!!!!!!!!!!!!!!!
eg:
正解爲:
tarjan 後縮點計算出度,如果出度爲0的點的個數爲1,那麼就是我們要找到的答案,排序輸出。
否則,如果個數大於1,或者此點不是愛心天使,那麼就輸出‘-1’。
因爲:
如果爲這種情況,則1,2,3爲一個強連通分量。
#include<iostream>
#include<stdio.h>
#include<algorithm>
#define kkklll 10002
using namespace std;
int to[10002],next[10002],head[1002],cnt;
void add(int x,int y){to[++cnt]=y;next[cnt]=head[x];head[x]=cnt;}
int rudu[1002],chudu[1002];
int min(int a,int b){return a<b?a:b;}
int deep[1002],low[1002],tim,v[1002],z[1002],inz[1002],top;
int ans,f[1002][1002],in[1002];
void tarjan(int x)
{
z[++top]=x,inz[x]=1,v[x]=1;
deep[x]=low[x]=++tim;
for(int i=head[x];i;i=next[i])
{
if(v[to[i]]==0) {tarjan(to[i]);low[x]=min(low[x],low[to[i]]);}
else{if(inz[to[i]]==1){low[x]=min(low[x],deep[to[i]]);}}
}
if(deep[x]==low[x])
{
ans++;
int t;
while(1)
{
t=z[top--];inz[t]=0;f[ans][++f[ans][0]]=t;in[t]=ans;
if(t==x){break;}
}
}
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
int i,j;
for(i=0;i<m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
add(a,b);
rudu[b]++;
}
for(i=1;i<=n;i++)
{
if(v[i]==0)
{
tarjan(i);
}
}
int ans1=0;
for(i=1;i<=ans;i++)
{
if(f[i][0]!=1) ans1++;
}
printf("%d\n",ans1);
for(i=1;i<=n;i++)
{
for(j=head[i];j;j=next[j])
{
if(in[to[j]]!=in[i])
{chudu[in[i]]++;}
}
}
int sum=0;
int pos;
for(i=1;i<=ans;i++)
{
if(chudu[i]==0){sum++;pos=i;}
}
if(sum!=1||f[pos][0]==1){printf("-1");}
else
{
int a=f[pos][0];
f[pos][0]=0;
sort(f[pos]+1,f[pos]+a+1);
for(i=1;i<=a;i++)
{
printf("%d ",f[pos][i]);
}
}
return 0;
}