标签:present sharp ems push define where data empty rom

Input
Output
Sample Input
0 0 1 0 3 3 (0,1) (0,2) (1,2) 2 0 5 7 (0,1) (0,2) (1,3) (1,2) (1,4) (2,3) (3,4)
Sample Output
0 1 3 0 2
idea:
At first,这道题和最小割十分相似,可是我们要将割点转换为割边,将一个点拆成入点和出点
然后将入点向出点连一条边权为1的边,表示这个点删掉的代价为1,每一条无向边(a,b)需要将a的出点连向b的入点,反之亦然
这样删掉点就相当于删掉a的入点到a的出点这一条边,完成了点边转化
每一次,我们需要枚举源点和汇点,取最小值,源点要求是一个出点,汇点是一个入点,求最小割即保留源点和汇点的情况下使原图断开的最大花费
输出答案即可,上代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define MAXN 30002
using namespace std;
queue<int> Q;
int vals[MAXN],tot,t,n,m,ii,ij,to[MAXN],nxt[MAXN],val[MAXN],fir[MAXN],cur[MAXN],dep[MAXN];
void read(){
char ch=getchar();
while(ch!=‘(‘) ch=getchar();
ch=getchar(); ii=0;
while(‘0‘<=ch && ch<=‘9‘) ii=(ii<<1)+(ii<<3)+ch-‘0‘,ch=getchar();
ch=getchar(); ij=0;
while(‘0‘<=ch && ch<=‘9‘) ij=(ij<<1)+(ij<<3)+ch-‘0‘,ch=getchar();
}
void ade(int u,int v,int z){
//cout<<u<<" "<<v<<" "<<z<<endl;
val[++tot]=z;
to[tot]=v;
nxt[tot]=fir[u];
fir[u]=tot;
}
bool bfs(int s,int t){
memset(dep,0,sizeof(dep));
dep[s]=1; while(!Q.empty()) Q.pop();
Q.push(s);
while(!Q.empty()){
int x=Q.front(); Q.pop();
for(int k=fir[x];k!=-1;k=nxt[k]){
if(val[k] && !dep[to[k]]){
dep[to[k]]=dep[x]+1;
Q.push(to[k]);
}
}
}
if(dep[t]) return 1;
return 0;
}
int dfs(int x,int dis,int t){
if(x==t) return dis;
for(int k=cur[x];k!=-1;k=nxt[k]){
cur[x]=k;
if(dep[to[k]]==dep[x]+1 && val[k]){
int z=dfs(to[k],min(dis,val[k]),t);
if(z){
val[k]-=z; val[k^1]+=z;
return z;
}
}
}
return 0;
}
int Dinic(int s,int t){
int res=0,d;
while(bfs(s,t)){
rep(i,0,n*2-1) cur[i]=fir[i];
d=dfs(s,99999999,t);
while(d){
res+=d;
d=dfs(s,99999999,t);
}
}
return res;
}
int main(){
while(~scanf("%d%d",&n,&m)){
memset(fir,-1,sizeof(fir)); tot=-1;
rep(i,1,m){
read();
if(ii==ij) continue;
ade(ii+n,ij,99999999); ade(ij,ii+n,0);
ade(ij+n,ii,99999999); ade(ii,ij+n,0);
}
rep(u,0,n-1) ade(u,u+n,1),ade(u+n,u,0);
if(n==0 || m<n-1){
puts("0");
continue;
}
if(n==1){
puts("1");
continue;
}
rep(i,0,tot) vals[i]=val[i];
int ans=99999999;
rep(i,n,n+n-2){
rep(j,i+1,n+n-1)
{
rep(k,0,tot) val[k]=vals[k];
ans=min(ans,Dinic(i,j-n));
}
}
if(ans==99999999) ans=n;
printf("%d\n",ans);
}
return 0;
}
标签:present sharp ems push define where data empty rom
原文地址:https://www.cnblogs.com/handsome-zlk/p/10436555.html