题意:在有向图 GG 中,每条边的长度均为 11,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件:
- 路径上的所有点的出边所指向的点都直接或间接与终点连通。
- 在满足条件11的情况下使路径最短。
注意:图 GG 中可能存在重边和自环,题目保证终点没有出边。
请你输出符合条件的路径的长度。
少有的题意简明的题目
解法:反向建图,bfs终点到源点的,记录每个点正的度数和反的度数,比较后再把正的图建出。最后bfs
#include<iostream> #include<cstring> #include<queue> using namespace std; const int MAXN=10005,MAXM=200005; struct Edge{int next,to;}edge[MAXM]; struct EDge{int u,v;}EDGE[MAXM]; int n,m,s,t,n_e,head[MAXN],cnt[MAXN][2],dis[MAXN]; bool vis[MAXN]; void spfa(int x); void bfs(int x); void addedge(int from,int to); int main() { cin>>n>>m; for(int i=1;i<=m;i++) { int u,v; cin>>u>>v; EDGE[i].u=u; EDGE[i].v=v; cnt[u][0]++; addedge(v,u); } cin>>s>>t; bfs(t); cnt[s][1]=cnt[s][0]; cnt[t][1]=cnt[t][0]; memset(edge,0,sizeof(edge)); memset(head,0,sizeof(head)); memset(vis,0,sizeof(vis)); memset(dis,0x7f,sizeof(dis)); for(int i=1;i<=m;i++) { int u=EDGE[i].u,v=EDGE[i].v; if( cnt[u][1]==cnt[u][0]&&cnt[v][1]==cnt[v][0] ) addedge(u,v); } spfa(s); if(dis[t]==dis[0]) cout<<"-1"; else cout<<dis[t]; return 0; } void addedge(int from,int to) { edge[++n_e].next=head[from]; edge[n_e].to=to; head[from]=n_e; } void bfs(int x) { queue<int> q; q.push(x); while(!q.empty()) { int now=q.front(); q.pop(); cnt[now][1]++; if(vis[now]) continue; vis[now]=1; for(int i=head[now];i;i=edge[i].next) q.push(edge[i].to); } } void spfa(int x) { queue<int> q; q.push(x); dis[x]=0; vis[x]=1; while(!q.empty()) { int u,v; u=q.front(); q.pop(); vis[u]=0; for(int i=head[u];i;i=edge[i].next) { v=edge[i].to; if(dis[v]>dis[u]+1) { dis[v]=dis[u]+1; if(!vis[v]) { vis[v]!=vis[v]; q.push(v); } } } } }