1. 程式人生 > >洛谷P2661 資訊傳遞 topo排序+dfs

洛谷P2661 資訊傳遞 topo排序+dfs

傳送門

這一題可以算是有向圖求最小環的模板題了

比如這個圖,第一輪遊戲2的生日傳到4,第二輪遊戲2的生日傳到3,第三輪遊戲2的生日傳到2自己

遊戲能進行的輪數就是圖中的最小環

先進行一次拓撲排序使圖中只剩下環,然後dfs求最小環的長度就行了

#include<iostream>
#include<vector>
#include<queue>
using namespace std;
int n,count;
int rd[200005],book[200005];
vector<int>g[200005];
void topo()//topo排序刪除所有入讀為0的點 
{ int i; queue<int>q; for(i=1;i<=n;i++) { if(rd[i]==0) { q.push(i); book[i]=1;//刪除頂點 } } while(q.size()) { int x=q.front(); q.pop(); for(i=0;i<g[x].size();i++)//與x相連的點入度減一 {
int y=g[x][i]; rd[y]--;; if(rd[y]==0) { q.push(y); book[y]=1;//刪除頂點 } } } } void dfs(int x) { count++; book[x]=1; for(int i=0;i<g[x].size();i++)//便利與x相鄰的頂點 { int y=g[x][i]; if(book[y]==0
)book[y]=1,dfs(y); } } void solve() { cin>>n; for(int i=1;i<=n;i++) { int a; cin>>a; rd[a]++;//入度加一 g[i].push_back(a); } topo(); int ans=9999999; for(int i=1;i<=n;i++) if(book[i]==0)//i號頂點沒有被刪除 { count=0; dfs(i); ans=min(ans,count); } cout<<ans<<endl; } int main() { solve(); }