CCF 習題 201512-4 送貨 (並查集 + DFS 找尤拉道路)
阿新 • • 發佈:2018-12-24
大體題意:
要求從1號出發,一筆畫經過所有的路,問是否有解,並列印字典序最小的解?
思路:
顯然是無向圖的尤拉道路!
先判連通,直接用並查集了,不連通直接-1了
連通的話,在看看每個點的度數,當奇點的個數不是0 並且不是2 肯定是-1
如果是2 的話,1號結點是偶數度數的話也是-1
否則我們就可以從1號結點直接dfs找路了!
注意:
不能再dfs之前就輸出路徑,這樣是不對的 = = 這樣只得了20分!
因為這個點可能不合適,因此我們要用的stack 最後輸出stack即可!
詳細見程式碼:
#include<cstdio> #include<cstring> #include<algorithm> #include<vector> #define mr make_pair #include<stack> using namespace std; const int maxn = 10001; bool g[maxn][maxn]; int n,m; int num[10001]; bool vis[maxn][maxn]; vector<int>G[maxn]; int fa[maxn]; stack<int>sk; int find(int x){ return fa[x] == x ? fa[x] : fa[x] = find(fa[x]); } void add(int x,int y){ int xx = find(x); int yy = find(y); if (xx != yy)fa[yy] = xx; } void dfs(int k){ int len = G[k].size(); for (int i = 0; i < len; ++i){ int t = G[k][i]; if (!vis[k][t]){ vis[k][t] = vis[t][k] = 1; dfs(t); sk.push(t); } } } int main(){ scanf("%d %d", &n, &m); for (int i = 0; i <= n; ++i)fa[i] = i; for (int i = 0; i < m ;++i){ int u,v; scanf("%d %d",&u,&v); add(u,v); G[u].push_back(v); G[v].push_back(u); num[u]++; num[v]++; } for (int i = 1; i <= n; ++i)sort(G[i].begin(),G[i].end()); bool GO = 1; int t1 = find(1); for (int i = 1; i <= n; ++i){ if (find(i) != t1){ GO = 0; break; } } if (!GO)return 0 * puts("-1"); int sum = 0; for (int i = 1; i <= n; ++i)if (num[i] & 1)++sum; if (sum != 0 && sum != 2)return 0 * puts("-1"); if (sum == 2 && (num[1] & 1) == 0) return 0 * puts("-1"); printf("1"); dfs(1); while(!sk.empty()){ printf(" %d",sk.top()); sk.pop(); } puts(""); return 0; }
問題描述
試題編號: | 201512-4 |
試題名稱: | 送貨 |
時間限制: | 1.0s |
記憶體限制: | 256.0MB |
問題描述: |
問題描述
為了增加公司收入,F公司新開設了物流業務。由於F公司在業界的良好口碑,物流業務一開通即受到了消費者的歡迎,物流業務馬上遍及了城市的每條街道。然而,F公司現在只安排了小明一個人負責所有街道的服務。 任務雖然繁重,但是小明有足夠的信心,他拿到了城市的地圖,準備研究最好的方案。城市中有n個交叉路口,m條街道連線在這些交叉路口之間,每條街道的首尾都正好連線著一個交叉路口。除開街道的首尾端點,街道不會在其他位置與其他街道相交。每個交叉路口都至少連線著一條街道,有的交叉路口可能只連線著一條或兩條街道。 小明希望設計一個方案,從編號為1的交叉路口出發,每次必須沿街道去往街道另一端的路口,再從新的路口出發去往下一個路口,直到所有的街道都經過了正好一次。 輸入格式 輸入的第一行包含兩個整數n, m,表示交叉路口的數量和街道的數量,交叉路口從1到n標號。 接下來m行,每行兩個整數a, b,表示和標號為a的交叉路口和標號為b的交叉路口之間有一條街道,街道是雙向的,小明可以從任意一端走向另一端。兩個路口之間最多有一條街道。 輸出格式 如果小明可以經過每條街道正好一次,則輸出一行包含m+1個整數p1 如果不存在方案使得小明經過每條街道正好一次,則輸出一個整數-1。 樣例輸入 4 5 1 2 1 3 1 4 2 4 3 4 樣例輸出 1 2 4 1 3 4 樣例說明 城市的地圖和小明的路徑如下圖所示。 樣例輸入 4 6 1 2 1 3 1 4 2 4 3 4 2 3 樣例輸出 -1 樣例說明 城市的地圖如下圖所示,不存在滿足條件的路徑。 評測用例規模與約定 前30%的評測用例滿足:1 ≤ n ≤ 10, n-1 ≤ m ≤ 20。 前50%的評測用例滿足:1 ≤ n ≤ 100, n-1 ≤ m ≤ 10000。 所有評測用例滿足:1 ≤ n ≤ 10000,n-1 ≤ m ≤ 100000。 |