codeforces723E One-Way Reform(尤拉通路)
阿新 • • 發佈:2019-01-22
第一次打線上賽,1456分來著,感覺自己模擬題做的不怎麼樣,總是想複雜,而且寫程式碼慢的要死,這套題說實話還算簡單,但只A了兩道,其他的題都很基礎,這題尤拉通路我剛好不會,所以寫一下。
題意:
n個城市之間m條雙向道路,現在把雙向道路變成單向,求讓出入度相同的城市最多的路線圖。
要點:
這題就是個尤拉通路問題,因為要把雙向變成單向,所以原本的出度如果是奇數,說明這個頂點的入度和出度不相等,原本是偶數的直接就是相等的,所以最大城市數就是n-出度奇數個數。現在問題是怎麼輸出最後的路線圖,我們引入一個新頂點,將所有出度為奇數的點與新頂點連線,這樣圖中所有點的出入度都相等。這裡說明一下出度為奇數的點一定是偶數個,因為一條邊對應兩個點,這裡多一個那邊就少一個。這樣對整個圖進行dfs輸出歐拉回路即可。
#include<iostream> #include<set> #include<algorithm> using namespace std; set<int> edge[210];//用set方便之後刪除邊 int t, n, m; void dfs(int i) { if (edge[i].empty())//如果當前頂點沒有出去的邊就返回 return; int x = *edge[i].begin(); edge[i].erase(x);//將經過的邊消除 edge[x].erase(i); if (i != n + 1 && x != n + 1)//新加入的點不參與輸出 printf("%d %d\n", i, x); dfs(x); } int main() { int i, j; scanf("%d", &t); while (t--) { scanf("%d%d", &n, &m); for (i = 0; i < 210; i++) edge[i].clear(); int u, v; for (i = 1; i <= m; i++) { scanf("%d%d", &u, &v); edge[u].insert(v); edge[v].insert(u); } for(i=1;i<=n;i++) if (edge[i].size() & 1) { edge[i].insert(n + 1); edge[n + 1].insert(i); } printf("%d\n", n-edge[n + 1].size()); for (i = 1; i <= n; i++) { while (!edge[i].empty()) { dfs(i); } } } return 0; }