//O(n^3)实现
#include <bits/stdc++.h>
using namespace std;
#define sfi(a) scanf("%d",&a)
#define sfd(a) scanf("%lf",&a)
#define sfl(a) scanf("%lld",&a)
#define sfs(a) scanf("%s",a)
#define rep(i,a,b) for(int i=int(a);i<int(b);++i)
#define dwn(i,b,a) for(int i=int(b-1);i>=int(a);--i)
#define mem(a,p) memset(a,p,sizeof(a))
typedef long long LL;
typedef unsigned UINT;
typedef unsigned long long ULL;
#define MAXN 305
const LL INF=1e16;
struct Stoer_Wagner
{
LL e[MAXN][MAXN];
int n;
LL w[MAXN];
bool vis[MAXN],bin[MAXN];
void init(int nn)
{
n=nn;
mem(e,0);
}
void AddEdge(int u,int v,int w)
{
e[u][v]+=w;
e[v][u]+=w;
}
LL Search(int &s,int &t)
{
mem(vis,0);
mem(w,0);
t=1;
while(bin[t])t++;
vis[t]=true;
while(true)
{
rep(i,1,n+1)
{
if(vis[i]||bin[i])continue;
w[i]+=e[t][i];
}
int p=-1;
rep(i,1,n+1)
{
if(vis[i]||bin[i])continue;
if(p==-1||w[i]>w[p])p=i;
}
if(p==-1)break;
s=t;
t=p;
vis[t]=true;
}
return w[t];
}
LL Solve()
{
mem(bin,0);
LL ret=INF;
int s,t;
rep(i,0,n-1)
{
LL pans=Search(s,t);
ret=min(ret,pans);
bin[t]=true;
rep(i,1,n+1)
{
if(bin[i])continue;
if(i==s)continue;
e[s][i]+=e[t][i];
e[i][s]+=e[i][t];
}
}
return ret;
}
}S;
int main()
{
int n,m,s;
while(scanf("%d%d%d",&n,&m,&s)==3)
{
if(n==0)break;
S.init(n);
rep(i,0,m)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
S.AddEdge(u,v,w);
}
printf("%lld\n",S.Solve());
}
return 0;
}
//堆优化版本,O(nmlogm)实现
#include <bits/stdc++.h>
using namespace std;
#define sfi(a) scanf("%d",&a)
#define sfd(a) scanf("%lf",&a)
#define sfl(a) scanf("%lld",&a)
#define sfs(a) scanf("%s",a)
#define rep(i,a,b) for(int i=int(a);i<int(b);++i)
#define dwn(i,b,a) for(int i=int(b-1);i>=int(a);--i)
#define mem(a,p) memset(a,p,sizeof(a))
typedef long long LL;
typedef unsigned UINT;
typedef unsigned long long ULL;
#define MAXN 305
const LL INF=1e16;
struct Stoer_Wagner
{
struct node
{
int i;
LL w;
node(int ii=0,LL ww=0):i(ii),w(ww){}
bool operator <(const node &p)const
{
return w<p.w;
}
};
struct edge
{
int v;
LL w;
edge(int vv=0,LL ww=0):v(vv),w(ww){}
};
edge e[MAXN][MAXN];
int etop[MAXN];
int ep[MAXN][MAXN];
priority_queue<node> q;
int n;
LL w[MAXN];
bool vis[MAXN],bin[MAXN];
void init(int nn)
{
n=nn;
mem(etop,0);
mem(ep,-1);
while(!q.empty())q.pop();
}
void AddEdge(int u,int v,LL w)
{
if(ep[u][v]==-1)
{
e[u][etop[u]]=edge(v,w);
ep[u][v]=etop[u]++;
}
else e[u][ep[u][v]].w+=w;
if(ep[v][u]==-1)
{
e[v][etop[v]]=edge(u,w);
ep[v][u]=etop[v]++;
}
else e[v][ep[v][u]].w+=w;
}
LL Search(int &s,int &t)
{
mem(vis,0);
mem(w,0);
t=1;
while(bin[t])t++;
q.push(node(t,0));
while(!q.empty())
{
node p=q.top();
q.pop();
if(vis[p.i])continue;
vis[p.i]=true;
rep(i,0,etop[p.i])
{
int &v=e[p.i][i].v;
if(vis[v]||bin[v])continue;
w[v]+=e[p.i][i].w;
q.push(node(v,w[v]));
}
s=t;
t=p.i;
}
return w[t];
}
LL Solve()
{
mem(bin,0);
LL ret=INF;
int s,t;
rep(i,0,n-1)
{
LL pans=Search(s,t);
ret=min(ret,pans);
bin[t]=true;
rep(i,0,etop[t])
{
int &v=e[t][i].v;
if(bin[v])continue;
if(v==s)continue;
AddEdge(s,v,e[t][i].w);
}
}
return ret;
}
}S;
int main()
{
int n,m,s;
while(scanf("%d%d%d",&n,&m,&s)==3)
{
if(n==0)break;
S.init(n);
rep(i,0,m)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
S.AddEdge(u,v,w);
}
printf("%lld\n",S.Solve());
}
return 0;
}
SW算法求全局最小割
最新推荐文章于 2023-09-28 15:19:28 发布