解题思路:
tarjan只处理出现了两个强联通分量的问题,要是出现大于1个的分量就输出-1。
其实这个问题可以看做是一个强连通分量里面的所有简单环是否存在至少一个公共交点。
那么我们假设一个点满足条件就等价于从这个点出发肯定最后不会滞留在一个死循环中,而是最后回到了出发点.对所有路径都满足。如果这个点不满足,那么应该再去找哪个点呢?这个点滞留在死循环中,那么就说明它不属于这个死循环的环,所以接下来的那个点一定是这两个环的交点,因为该点绝对满足不会进入这两个环的死循环,接下来就是这样找下去,直到遇到交点是已经遇到过的,那么说明有两个交集点为0的环,则输出-1.由于这样找在有解的情况是最快的,所以时间一多说明几乎是无解的,则可以限时查询的时间。
#include<bits/stdc++.h>
using namespace std;
const int mx = 1e5 + 10;
int n,m,in[mx],ty,type[mx],d,mark;
vector <int> vec[mx];
int dfn[mx],id[mx],size,is,sta[mx];
int vis[mx],flag;
bool vic[mx];
void tarjan(int x)
{
dfn[x] = id[x] = ++is;
vis[x] = 1;
sta[++size] = x;
for(int i=0;i<vec[x].size();i++){
int son = vec[x][i];
if(!dfn[son]){
tarjan(son);
id[x] = min(id[x],id[son]);
}else if(vis[son]) id[x] = min(id[x],dfn[son]);
}
if(dfn[x]==id[x]){
ty++;
if(sta[size]!=x) d++,mark = ty;
while(sta[size]!=x){
type[sta[size]] = ty;
vis[sta[size]] = 0;
size--;
}type[x] = ty,size--,vis[x] = 0;
}
}
void dfs(int x,int num)
{
if(flag) return ;
for(int i=0;i<vec[x].size();i++)
{
if(flag) return;
int son = vec[x][i];
if(vis[son]==num){
if(vic[son]) flag = -1;
else flag = son,vic[son] = 1;
}
if(vis[son]<num) vis[son] = num,dfs(son,num);
}
vis[x] = num + 1;
}
double TIME(){//获得单位运行时间
return 1.0*clock()/CLOCKS_PER_SEC;
}
int check(int x,int num)
{
while(TIME()<0.5){
vis[x] = num + 1;
dfs(x,num);
if(!flag) return x;
if(flag==-1) return -1;
x = flag,num += 2,flag = 0;
}
return -1;
}
int main()
{
scanf("%d%d",&n,&m);
int a,b,c = 0,ans;
for(int i=1;i<=m;i++){
scanf("%d%d",&a,&b);
vec[a].push_back(b);
}
for(int i=1;i<=n;i++)
if(!dfn[i]) tarjan(i);
if(d>1) return 0*puts("-1");
for(int i=1;i<=n;i++){
if(type[i]==mark){
return 0*printf("%d\n",check(i,1));
}
}
return 0;
}