洛谷P2661 資訊傳遞 topo排序+dfs
阿新 • • 發佈:2018-12-05
這一題可以算是有向圖求最小環的模板題了
比如這個圖,第一輪遊戲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(); }