HDU3342有向圖判圈DFS&&拓撲排序法
阿新 • • 發佈:2017-07-22
ble 成了 target href tar -- targe space 排序
HDU3342 Legal or Not
題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=3342
題目意思:一群大牛互相問問題,大牛有不會的,會被更厲害的大牛解答,更厲害的大牛是會的東西比大牛多,但是有的時候更厲害的大牛會裝弱,出來問問題,這樣就被大牛解答了。這樣就形成了一個圈。題目的意思就是讓你在一個有向圖裏面判斷是否存在環。我們可以通過dfs和拓撲排序兩種方法。
DFS的代碼:
//Author: xiaowuga #include <bits/stdc++.h> #define maxx INT_MAX #define minn INT_MIN #defineinf 0x3f3f3f3f const long long N=100000+10; using namespace std; typedef long long L; vector<int>q; vector<int>p[N]; int in[N]; int main(){ ios::sync_with_stdio(false);cin.tie(0); int n,m; while(cin>>n>>m){ q.clear(); memset(in,0,sizeof(in)); for(inti=1;i<=n;i++) p[i].clear(); q.clear(); int reward[N]; for(int i=1;i<=n;i++) reward[i]=888; for(int i=0;i<m;i++){ int a,b; cin>>a>>b; p[b].push_back(a); in[a]++; } int ct=0,ans=0;for(int i=1;i<=n;i++) if(!in[i]) {q.push_back(i);ans+=reward[i];} while(q.size()!=0){ int t=q.back();q.pop_back(); ct++; for(int i=0;i<p[t].size();i++){ int x=p[t][i]; if(--in[x]==0){ q.push_back(x); reward[x]=max(reward[x],reward[t]+1); ans+=reward[x]; } else{ reward[x]=max(reward[x],reward[t]+1); } } } if(ct!=n){ cout<<-1<<endl; } else cout<<ans<<endl; } return 0; }
dfs的思路,就是一路遍歷做標記,然後如果遍歷到已經遍歷過的就說明存在環,但是一找到環就可以break,跳出,結束dfs,可以剪枝,不然會超時,因為一個點可能遍歷很多遍,所以dfs是比較慢的。
拓撲排序的做法
為什麽可以判圈我在我的另外一篇博文裏面已經說清楚了:http://www.cnblogs.com/xiaowuga/p/7218382.html
還是把一個環縮成一個點思想,環上的大小關系的等價的,從而無法遍歷所有的點,通過遍歷點的數量來判斷是否形成環。
代碼:
//Author: xiaowuga #include <bits/stdc++.h> #define maxx INT_MAX #define minn INT_MIN #define inf 0x3f3f3f3f const long long N=100000+10; using namespace std; typedef long long L; vector<int>q; vector<int>p[N]; int in[N]; int main(){ ios::sync_with_stdio(false);cin.tie(0); int n,m; while(cin>>n>>m&&n&&m){ q.clear(); memset(in,0,sizeof(in)); for(int i=0;i<n;i++) p[i].clear(); q.clear(); for(int i=0;i<m;i++){ int a,b; cin>>a>>b; p[b].push_back(a); in[a]++; } int ct=0; for(int i=0;i<n;i++) if(!in[i]) {q.push_back(i);} while(q.size()!=0){ int t=q.back();q.pop_back(); ct++; for(int i=0;i<p[t].size();i++){ int x=p[t][i]; if(--in[x]==0){ q.push_back(x); } } } if(ct!=n){ cout<<"NO"<<endl; } else cout<<"YES"<<endl; } return 0; }
HDU3342有向圖判圈DFS&&拓撲排序法