VIJOS-P1626 爱在心中

来源:互联网 发布:华为云计算hcie 编辑:程序博客网 时间:2024/05/16 07:29

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 10002using 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;}