标签:
第一次做这种题, 尽管ac了但是完全不知道为什么这么做。
题目就是给一些边, 有向边与无向边混合, 问你是否存在欧拉回路。
做法是先对每个点求入度和出度, 如果一条边是无向边, 就随便指定一个方向, 然后连一条边, 权值为1。 最后统计入度出度, 如果一个点的(入度-出度)%2==1, 就说明不存在欧拉回路。 如果全都满足, 就判断每个点的入度出度的大小关系, 入度>出度, 就向汇点连一条边, 权值为(入度-出度)/2, 相反的话就向源点连边。
跑一遍最大流, 看是否满流, 如果满流就说明存在。
完全不理解.....还是太弱。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define pb(x) push_back(x) 4 #define ll long long 5 #define mk(x, y) make_pair(x, y) 6 #define lson l, m, rt<<1 7 #define mem(a) memset(a, 0, sizeof(a)) 8 #define rson m+1, r, rt<<1|1 9 #define mem1(a) memset(a, -1, sizeof(a)) 10 #define mem2(a) memset(a, 0x3f, sizeof(a)) 11 #define rep(i, a, n) for(int i = a; i<n; i++) 12 #define ull unsigned long long 13 typedef pair<int, int> pll; 14 const double PI = acos(-1.0); 15 const double eps = 1e-8; 16 const int mod = 1e9+7; 17 const int inf = 1061109567; 18 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; 19 const int maxn = 210; 20 const int maxE = 10005; 21 int indeg[maxn], outdeg[maxn]; 22 int head[maxE], s, t, num, q[maxE], dis[maxn]; 23 struct node 24 { 25 int to, nextt, c; 26 }e[maxE]; 27 void init() { 28 mem1(head); 29 num = 0; 30 mem(indeg); 31 mem(outdeg); 32 } 33 void add(int u, int v, int c) { 34 e[num].to = v; e[num].nextt = head[u]; e[num].c = c; head[u] = num++; 35 e[num].to = u; e[num].nextt = head[v]; e[num].c = 0; head[v] = num++; 36 } 37 int bfs() { 38 mem(dis); 39 int st = 0, ed = 0; 40 q[ed++] = s; 41 dis[s] = 1; 42 while(st<ed) { 43 int u = q[st++]; 44 for(int i = head[u]; ~i; i = e[i].nextt) { 45 int v = e[i].to; 46 if(e[i].c&&!dis[v]) { 47 dis[v] = dis[u]+1; 48 if(v == t) 49 return 1; 50 q[ed++] = v; 51 } 52 } 53 } 54 return 0; 55 } 56 int dfs(int u, int limit) { 57 if(u == t) 58 return limit; 59 int cost = 0; 60 for(int i = head[u]; ~i; i = e[i].nextt) { 61 int v = e[i].to; 62 if(e[i].c&&dis[v] == dis[u]+1) { 63 int tmp = dfs(v, min(limit-cost, e[i].c)); 64 if(tmp>0) { 65 e[i].c -= tmp; 66 e[i^1].c += tmp; 67 cost += tmp; 68 if(limit == cost) 69 break; 70 } else { 71 dis[v] = -1; 72 } 73 } 74 } 75 return cost; 76 } 77 int dinic() { 78 int ans = 0; 79 while(bfs()) { 80 ans += dfs(s, inf); 81 } 82 return ans; 83 } 84 int main() 85 { 86 int T, n, m, x, y, z; 87 cin>>T; 88 while(T--) { 89 scanf("%d%d", &n, &m); 90 init(); 91 s = 0, t = n+1; 92 while(m--) { 93 scanf("%d%d%d", &x, &y, &z); 94 indeg[y]++; 95 outdeg[x]++; 96 if(z == 0) { 97 add(x, y, 1); 98 } 99 } 100 int flag = 0; 101 for(int i = 1; i<=n; i++) { 102 if(abs(indeg[i]-outdeg[i])%2==1) { 103 flag = 1; 104 break; 105 } 106 } 107 if(flag) { 108 cout<<"impossible"<<endl; 109 continue; 110 } 111 int sum = 0; 112 for(int i = 1; i<=n; i++) { 113 if(indeg[i]<outdeg[i]) { 114 add(s, i, (outdeg[i]-indeg[i])/2); 115 } else { 116 add(i, t, (indeg[i]-outdeg[i])/2); 117 sum += (indeg[i]-outdeg[i])/2; 118 } 119 } 120 int ans = dinic(); 121 if(ans == sum) { 122 cout<<"possible"<<endl; 123 } else { 124 cout<<"impossible"<<endl; 125 } 126 } 127 }
poj1637 Sightseeing tour 混合图欧拉回路判定
标签:
原文地址:http://www.cnblogs.com/yohaha/p/5011399.html