題意:給你一張n個點m條邊的圖,其中有一些邊是有向邊,有一些邊是無向邊,題目要求你對所有無向邊選擇乙個方向,使得整個圖成為有向無環圖(dag),若無法做到則輸出-1。
思路:如果給定的有向邊已經形成環了,那麼再怎麼改無向邊,都無法做到。如果有向邊沒有形成環,那麼就可以做到。我們把有向邊連線起來,無向邊不連線(看做乙個個孤立的點),對整張圖進行拓撲排序,因為每個點只有1次入隊出隊的機會,所以我們可以得到每個點出隊的順序。我們把每條邊按照這個順序輸出就行。(無向邊迎合有向邊的方向,有向邊中,起點肯定比終點早出隊,所以我們只要把無向邊也遵從這個規則就行。)
#include
#pragma gcc optimize("ofast")
#define endl '\n'
#define null null
#define ls p<<1
#define rs p<<1|1
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define ll long long
//#define int long long
#define pii pair
#define pdd pair
#define ull unsigned long long
#define all(x) x.begin(),x.end()
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ct cerr<<"time elapsed:"<<1.0*clock()/clocks_per_sec<<"s.\n";
char
*fs,
*ft,buf[
1<<20]
;#define gc() (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<20,stdin),fs==ft))?0:*fs++;
inline
intread()
while
(ch>=
'0'&&ch<=
'9')
return x*f;
}using
namespace std;
const
int n=
2e5+5;
const
int inf=
0x3f3f3f3f
;const
int mod=
998244353
;const
double eps=
1e-6
;const
double pi=
acos(-
1);vector<
int>e[n]
;int in[n]
;int p[n]
;signed
main()
for(
int i=
1;i<=m;i++)}
queue<
int>q;
for(
int i=
1;i<=n;i++
)int tot=0;
while
(!q.
empty()
)}if(tot!=n)
cout<<
"no"
}
E Directing Edges 拓撲排序
思路 拓撲排序。考慮只由有向邊組成的圖。顯然若該圖有環顯然無解。否則必然有解。因為 該有向圖是乙個dag dagda g能構成乙個拓撲序,假設當前我們有一條無向邊從拓撲序尾連向拓撲序首,顯然我們可以改變該邊的方向 即讓拓撲序較小的點指向拓撲序較大的點,這樣就不會破壞原有的拓撲序,使得該圖仍為dag ...
Legal or Not hdu3342拓撲排序
題意 判斷圖中是否有環存在 思路 簡單的拓撲排序 將有關係的點,加乙個有向邊,然後記錄出入度,先找入度為0的點,將和他聯絡的點入度 1,再找入度為0的直到沒有點為止,判斷點是否全訪問過,如果是說明不存在環,如果不是就說明有環存在 include include include include inc...
HDU3342Legal or Not 拓撲排序
有向圖判斷是否成環 如果是環輸出no 只要入度為0的點的個數 等於 總的點的個數則無環 includeusing namespace std input by bxd define rep i,a,b for int i a i b i define ri n scanf d n define ri...