“浪潮杯”山东省第六届ACM大学生程序设计竞赛 Circle of Friends

先用强联通分量缩点,然后深搜找最短路径就行了,
#include <bits/stdc++.h>
using namespace std;
const int max_V=100005;
vector<int>G[max_V];
vector<int>rG[max_V];
vector<int>vs;
int used[max_V];
int cmp[max_V],cnt[max_V],vis[max_V];
int V;
void dfs(int v)
{
    used[v]=1;
    for(int i=0; i<(int)G[v].size(); i++)
    {
        if(!used[G[v][i]])
            dfs(G[v][i]);
    }
    vs.push_back(v);
}
void rdfs(int v,int k)
{
    cnt[k]++;
    used[v]=1;
    cmp[v]=k;
    for(int i=0; i<(int)rG[v].size(); i++)
    {
        if(!used[rG[v][i]])
            rdfs(rG[v][i],k);
    }
}

int Kosaraju()
{
    int k=0;
    memset(used,0,sizeof(used));
    vs.clear();
    for(int v=0; v<V; v++)
    {
        if(!used[v])dfs(v);
    }
    memset(used,0,sizeof(used));
    for(int i=V-1; i>=0; i--)
    {
        if(!used[vs[i]])
        {
            rdfs(vs[i],k++);
        }
    }
    return k;
}
int flag=0;
int dfs1(int u,int now)
{
if(used[u]!=-1)return used[u];
 if(cmp[u]==cmp[V-1])
 {flag=1;return now;}
 int ans=100001;
 for(int i=0;i<(int)G[u].size();i++)
 {
     int tmp=G[u][i];
     if(vis[tmp])continue;
     vis[tmp]=1;
     ans=min(ans,dfs1(G[u][i],now+(cmp[u]==cmp[tmp]?0:1)));
     vis[tmp]=0;
 }
 used[u]=ans;
 return ans;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
    int m,x,y;
    scanf("%d%d",&V,&m);
    for(int i=0;i<V;i++)G[i].clear(),rG[i].clear();
    memset(cnt,0,sizeof(cnt));
    while(m--)
    {
        scanf("%d%d",&x,&y);
        G[x].push_back(y);
        rG[y].push_back(x);
    }
    Kosaraju();
    if(cmp[0]==cmp[V-1])
        {printf("0\n");
    continue;}
    memset(used,-1,sizeof(used));
    memset(vis,0,sizeof(vis));
    vis[0]=1;
    flag=0;
    dfs1(0,0);
    if(flag==0)
    {
        printf("-1\n");
    continue;
    }
     printf("%d\n",used[0]);
}
    return 0;
}

猜你喜欢

转载自blog.csdn.net/clx55555/article/details/80118015