判定最小割唯一性,先做一遍最大流,然后正向遍历得到集合S, 反向遍历得到集合T,如果ST不想交切相加等于全集,那么就是唯一的
反向遍历是容量取边edge[i^1].cap, 感觉非常巧妙
#include <set>
#include <map>
#include <cmath>
#include <queue>
#include <stack>
#include <string>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const double PI = acos(-1.0);
template <class T> inline T MAX(T a, T b){if (a > b) return a;return b;}
template <class T> inline T MIN(T a, T b){if (a < b) return a;return b;}
const LL MOD = 1000000007LL;
const int dir[4][2] = {1, 0, -1, 0, 0, -1, 0, 1};
const int INF = 0x3f3f3f3f;
int cnt1, cnt2;
bool vis[805];
const int MAXN = 880 , MAXE = 44000;
struct Arclist{
struct Edge{int v,cap,next;}E[MAXN+MAXE<<1];
int head[MAXN],cur;
void init(){memset(head, -1, sizeof(head));cur=0;}
void add(int u,int v,int cap=1){
E[cur].v=v;E[cur].cap=cap;
E[cur].next=head[u];head[u]=cur++;
E[cur].v=u;E[cur].cap=0;
E[cur].next=head[v];head[v]=cur++;
}
int SAP(int S,int T,int N){
int maxflow=0,pre[MAXN],dis[MAXN]={},gap[MAXN]={};
int cur[MAXN];memcpy(cur, head, sizeof(head));
gap[0]=N+1;++gap[dis[S]=1];
for(int u=pre[S]=S;dis[S]<=N;++gap[++dis[u]],u=pre[u]){
for(bool flag=true;flag;){flag=false;
for(int&p=cur[u];~p;p=E[p].next){
if(!E[p].cap||dis[u]!=dis[E[p].v]+1)continue;
flag=true;pre[E[p].v]=u;u=E[p].v;
if(u==T){
int aug=INF;
for(int i=S;i!=T;i=E[cur[i]].v)
if (aug > E[cur[i]].cap)
{
u = i; aug = E[cur[i]].cap;
}
for(int i=S;i!=T;i=E[cur[i]].v){
E[cur[i]].cap-=aug;
E[cur[i]^1].cap+=aug;
}
maxflow+=aug;
}
break;
}
}
if(--gap[dis[u]]==0)break;
dis[u]=N;
for(int p=head[u];~p;p=E[p].next)
if (E[p].cap && dis[u] > dis[E[p].v]) {dis[u] = dis[E[p].v]; cur[u] = p;}
}
return maxflow;
}
void DFS(int u)
{
for (int i = head[u]; ~i; i = E[i].next)
{
int v = E[i].v;
if (E[i].cap && !vis[v])
{
cnt1++;
vis[v] = 1;
DFS(v);
}
}
}
void RDFS(int u)
{
for (int i = head[u]; ~i; i = E[i].next)
{
int v = E[i].v;
if (E[i ^ 1].cap && !vis[v])
{
cnt2++;
vis[v] = 1;
RDFS(v);
}
}
}
}flow;
int main()
{
int n, m, a, b;
while (scanf("%d%d%d%d", &n, &m, &a, &b) , n | m | a | b)
{
int i, j, k, u, v, w;
flow.init();
for (i = 0; i < m; ++i)
{
scanf("%d%d%d", &u, &v, &w);
flow.add(u, v, w);
flow.add(v, u, w);
}
flow.SAP(a, b, n);
cnt1 = cnt2 = 0;
memset(vis, false, sizeof(vis));
vis[a] = 1;
flow.DFS(a);
memset(vis, false, sizeof(vis));
vis[b] = 1;
flow.RDFS(b);
if (cnt1 + cnt2 == n - 2) printf("UNIQUE\n");
else printf("AMBIGUOUS\n");
}
return 0;
}