题意为判断最小割的唯一性。
求最大流之后,考虑残量网络,从源点和汇点出发分别遍历,最后如果还有没被遍历到的点,则最小割不唯一。
#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;
}