VIJOS 1626 爱在心中

这道题目很显然是强连通的题目,用Tarjan算法求出强连通分量之后,要注意一些细节,
单个人不算爱心天使!靠靠靠。。所以强连通分量要特判的。
很显然如果入度为0的强连通分量有2个或以上,就不行了。
而且如果这个分量是一个人的话,还是-1囧。。我基本靠STL。。真爽饿(*^__^*)
幸好样例很强大,1AC了(*^__^*)
Code:

#include<iostream>#include<cstdio>#include<algorithm>#include<cmath>#include<cstdlib>#include<cstring>#include<string>#include<vector>#include<set>#include<queue>#include<map>#define rep(i,n) for(int i=0;i<n;i++)#define For(i,a,b) for(int i=a;i<=b;i++)#define tr(i,x) for(typeof(x.begin()) i=x.begin();i!=x.end();i++)#define all(x) x.begin(),x.end()#define pb push_backusing namespace std;typedef vector<int> vi;typedef vector<vi> vvi;typedef pair<int,int> ii;const int inf=~0U>>1,maxn=1000;int n,m;vvi E;vi ord,low,inStack,Stack,id;int cnt=0,snt=0;int dfs(int x){ ord[x]=low[x]=++cnt; inStack[x]=true;Stack.pb(x); tr(i,E[x]) if(!ord[*i]) low[x]=min(low[x],dfs(*i)); else if(inStack[*i]) low[x]=min(low[x],ord[*i]); if(ord[x]==low[x]) { int u;do{u=Stack.back();Stack.pop_back();id[u]=snt;inStack[u]=false;}while(u!=x); snt++; } return low[x];}void Init(){ cin>>n>>m;int s,t; E.resize(n); while(m–) { scanf("%d %d",&s,&t); E[t-1].pb(s-1); }}void Work(){ vi In,Num; ord=low=inStack=id=vi(n,0); rep(i,n)if(!ord[i])dfs(i); In=Num=vi(snt,0); rep(i,n)tr(e,E[i]) if(id[i]!=id[*e]) In[id[*e]]++; rep(i,n) Num[id[i]]++; int t=0; rep(i,snt)if(Num[i]>1) ++t; cout<<t<<endl; if(count(all(In),0)>1) cout<<-1<<endl; else { int ans=find(all(In),0)-In.begin(); if(Num[ans]==1){cout<<-1<<endl;return;} rep(i,n)if(id[i]==ans)cout<<i+1<<" "; cout<<endl; }}int main(){ //freopen("in","r",stdin); Init(); Work();}

Leave a Reply

Your email address will not be published. Required fields are marked *