ZOJ2587 Unique Attack

来源:互联网 发布:java资料下载 编辑:程序博客网 时间:2024/05/16 08:03

题意为判断最小割的唯一性。

求最大流之后,考虑残量网络,从源点和汇点出发分别遍历,最后如果还有没被遍历到的点,则最小割不唯一。

#include <cstdio>#include <cstring>#include <vector>#include <queue>#include <algorithm>using namespace std;struct Edge{int from, to, cap, flow;Edge(int ff,int tt,int cc,int fl) {from=ff; to=tt; cap=cc; flow=fl;}};const int INF = 0x7f7f7f7f;const int maxn = 805;int n,m,_m,s,t;vector<Edge> edges;vector<int> g[maxn];bool vis[maxn];int d[maxn];int cur[maxn];void init(){edges.clear();for (int i=1;i<=n;i++) g[i].clear();}void AddEdge(int from, int to, int cap){edges.push_back(Edge(from, to, cap, 0));edges.push_back(Edge(to, from, 0, 0));m = edges.size();g[from].push_back(m-2);g[to].push_back(m-1);}bool bfs(){memset(vis, 0, sizeof(vis));queue<int> Q;Q.push(s);d[s] = 0;vis[s] = 1;while (!Q.empty()){int x = Q.front(); Q.pop();for (int i = 0; i < g[x].size(); i++){Edge& e = edges[g[x][i]];if (!vis[e.to] && e.cap > e.flow){vis[e.to] = 1;d[e.to] = d[x]+1;Q.push(e.to);}}}return vis[t];}int dfs(int x, int a){if (x == t || a == 0) return a;int flow = 0, f;for (int& i = cur[x]; i < g[x].size(); i++){Edge& e = edges[g[x][i]];if (d[x]+1 == d[e.to] && (f = dfs(e.to, min(a, e.cap-e.flow))) > 0){e.flow += f;edges[g[x][i]^1].flow -= f;flow += f;a -= f;if (a == 0) break;}}return flow;}int maxflow(){int flow = 0;while (bfs()){memset(cur,0,sizeof(cur));flow += dfs(s, INF);}return flow;}void dfs1(int u){vis[u]=1;for (int i = 0; i < g[u].size(); i++){Edge& e = edges[g[u][i]];if (!vis[e.to] && e.cap>e.flow)dfs1(e.to);}}void dfs2(int u){vis[u]=1;for (int i = 0; i < g[u].size(); i++){Edge& e = edges[g[u][i]^1];if (!vis[e.from] && e.cap>e.flow)dfs2(e.from);}}int main(){int a,b,c;while (scanf("%d%d%d%d",&n,&_m,&s,&t)==4 && (n||_m||s||t)){init();while (_m--){scanf("%d%d%d",&a,&b,&c);AddEdge(a,b,c);AddEdge(b,a,c);}maxflow();memset(vis,0,sizeof(vis));dfs1(s);dfs2(t);bool yes=1;for (int i=1;i<=n;i++)if (!vis[i]) yes=0;if (yes) puts("UNIQUE");else puts("AMBIGUOUS");}return 0;}


原创粉丝点击