网络流裸题 HDU 3549
Sample input:
2
3 2
1 2 1
2 3 1
3 3
1 2 1
2 3 1
1 3 1
Sample output:
Case 1: 1
Case 2: 2
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define LL long long
#define inf 10000010
using namespace std;
queue<int> q;
int c[1010][1010],f[1010],pre[1010];
int n,m;
int bfs(int src,int des)
{
while(!q.empty())
q.pop();
memset(pre,-1,sizeof pre);
f[src]=inf;
q.push(src);
int now;
while(!q.empty())
{
now=q.front();
q.pop();
if(now==des)
break;
for(int next=1; next<=m; next++)
{
if(next==src||c[now][next]<=0||pre[next]!=-1)
continue;
pre[next]=now;
f[next]=min(f[now],c[now][next]);
q.push(next);
}
}
if(pre[des]==-1) return -1;
else return f[des];
}
int maxflow(int src,int des)
{
int cnt,ans=0;
int front,now;
while((cnt=bfs(src,des))!=-1)
{
front=pre[des];
now=des;
while(front!=-1)
{
c[front][now]-=cnt;
c[now][front]+=cnt;
now=front;
front=pre[now];
}
ans+=cnt;
}
return ans;
}
int main()
{
int t;
scanf("%d",&t);
int tt=t;
int kk=0;
while(t--)
{
kk++;
scanf("%d%d",&m,&n);
memset(c,0,sizeof c);
int u,v,val;
for(int i=1; i<=n; i++)
{
scanf("%d%d%d",&u,&v,&val);
if(u==v)
continue;
else
c[u][v]+=val;
}
printf("Case %d: %d\n",kk,maxflow(1,m));
}
return 0;
}
最小费用最大流 POJ 2135
Sample input:
4 5
1 2 1
2 3 1
3 4 1
1 3 2
2 4 2
Sample output:
6
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define LL long long
#define inf 10000010
using namespace std;
queue<int> q;
int c[1010][1010],f[1010],pre[1010];
int n,m;
int bfs(int src,int des)
{
while(!q.empty())
q.pop();
memset(pre,-1,sizeof pre);
f[src]=inf;
q.push(src);
int now;
while(!q.empty())
{
now=q.front();
q.pop();
if(now==des)
break;
for(int next=1; next<=m; next++)
{
if(next==src||c[now][next]<=0||pre[next]!=-1)
continue;
pre[next]=now;
f[next]=min(f[now],c[now][next]);
q.push(next);
}
}
if(pre[des]==-1) return -1;
else return f[des];
}
int maxflow(int src,int des)
{
int cnt,ans=0;
int front,now;
while((cnt=bfs(src,des))!=-1)
{
front=pre[des];
now=des;
while(front!=-1)
{
c[front][now]-=cnt;
c[now][front]+=cnt;
now=front;
front=pre[now];
}
ans+=cnt;
}
return ans;
}
int main()
{
int t;
scanf("%d",&t);
int tt=t;
int kk=0;
while(t--)
{
kk++;
scanf("%d%d",&m,&n);
memset(c,0,sizeof c);
int u,v,val;
for(int i=1; i<=n; i++)
{
scanf("%d%d%d",&u,&v,&val);
if(u==v)
continue;
else
c[u][v]+=val;
}
printf("Case %d: %d\n",kk,maxflow(1,m));
}
return 0;
}
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn=600;
const int maxm=30000;
const int inf=1<<29;
int n,m,k,e,st,des,num,head[maxn],pnt[maxm],nxt[maxm],flow[maxm],level[maxn],q[maxn],cnta[maxn],cntb[maxn];
char str[maxn][30];
void AddEdge(int u,int v,int c)
{
pnt[e]=v;nxt[e]=head[u];flow[e]=c;head[u]=e++;
pnt[e]=u;nxt[e]=head[v];flow[e]=0;head[v]=e++;
}
bool BFS()
{
memset(level,0,sizeof(level));
level[st]=1;
int pre=0,last=0;
q[last++]=st;
while(pre<last)
{
if(q[pre]==des)
return true;
for(int i=head[q[pre]];i!=-1;i=nxt[i])
if(flow[i]&&!level[pnt[i]])
{
level[pnt[i]]=level[q[pre]]+1;
q[last++]=pnt[i];
}
pre++;
}
return false;
}
int DFS(int u,int sum)
{
if(u==des)
return sum;
for(int i=head[u],t;i!=-1;i=nxt[i])
if(flow[i]&&level[pnt[i]]==level[u]+1&&(t=DFS(pnt[i],min(sum,flow[i]))))
{
flow[i]-=t;
flow[i^1]+=t;
return t;
}
return level[u]=0;
}
int maxflow()
{
int ans=0;
while(BFS())
while(1)
{
int val=DFS(st,inf);
if(!val)
break;
ans+=val;
}
return ans;
}
int GetNum(char *name)
{
for(int i=1;i<num;i++)
if(!strcmp(str[i],name))
return i;
return -1;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
e=0,num=1;
memset(head,-1,sizeof(head));
memset(cnta,0,sizeof(cnta));
memset(cntb,0,sizeof(cntb));
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%s",str[num]);
int index=GetNum(str[num]);
if(index==-1)
cnta[num++]++;
else
cnta[index]++;
}
scanf("%d",&m);
char a[101],b[30];
for(int i=0;i<m;i++)
{
scanf("%s%s",a,b);
int index=GetNum(b);
if(index==-1)
{
strcpy(str[num],b);
cntb[num++]++;
}
else
cntb[index]++;
}
st=0,des=num++;
for(int i=1;i<num;i++)
{
if(cnta[i])
AddEdge(i,des,cnta[i]);
if(cntb[i])
AddEdge(st,i,cntb[i]);
}
scanf("%d",&k);
for(int i=0;i<k;i++)
{
scanf("%s%s",a,b);
int numa=GetNum(a);
int numb=GetNum(b);
if(numa==-1)
{
strcpy(str[num],a);
numa=num++;
}
if(numb==-1)
{
strcpy(str[num],b);
numb=num++;
}
AddEdge(numa,numb,inf);
}
printf("%d\n",m-maxflow());
}
return 0;
}
#include<queue>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf 100000010
#define MAXN 100010
using namespace std;
char e[110][110];
int tol,head[MAXN],dis[MAXN],vis[MAXN],pre[MAXN];
struct Edge
{
int to,next,cap,flow,cost;
} edge[MAXN];
void addedge(int u,int v,int cap,int cost)
{
edge[tol].to=v;
edge[tol].cap=cap;
edge[tol].cost=cost;
edge[tol].flow=0;
edge[tol].next=head[u];
head[u]=tol++;
edge[tol].to=u;
edge[tol].cap=0;
edge[tol].cost=-cost;
edge[tol].flow=0;
edge[tol].next=head[v];
head[v]=tol++;
}
bool spfa(int s,int t)
{
queue<int>q;
for(int i = 0; i <MAXN; i++)
{
dis[i] = inf;
vis[i] = false;
pre[i] = -1;
}
dis[s] = 0;
vis[s] = true;
q.push(s);
while(!q.empty())
{
int u = q.front();
q.pop();
vis[u] = false;
for(int i = head[u]; i != -1; i = edge[i].next)
{
int v = edge[i].to;
if(edge[i].cap > edge[i].flow &&
dis[v] > dis[u] + edge[i].cost )
{
dis[v] = dis[u] + edge[i].cost;
pre[v] = i;
if(!vis[v])
{
vis[v] = true;
q.push(v);
}
}
}
}
if(pre[t] == -1)return false;
else return true;
}
int MinCostMaxFlow(int s,int t,int &cost)
{
int flow=0;
cost=0;
while(spfa(s,t))
{
int Min=inf;
for(int i=pre[t]; i!=-1; i=pre[edge[i^1].to])
{
if(Min>edge[i].cap-edge[i].flow)
Min=edge[i].cap-edge[i].flow;
}
for(int i=pre[t]; i!=-1; i=pre[edge[i^1].to])
{
edge[i].flow+=Min;
edge[i^1].flow-=Min;
cost+=edge[i].cost*Min;
}
flow+=Min;
}
return flow;
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n==0&&m==0)
break;
memset(e,0,sizeof e);
getchar();
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
scanf("%c",&e[i][j]);
getchar();
}
tol=0;
memset(head,-1,sizeof head);
int k=1;
int a[110][110],b[110][110];
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
{
if(e[i][j]=='m')
a[i][j]=k++;
}
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
{
if(e[i][j]=='H')
b[i][j]=k++;
}
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
{
if(e[i][j]=='m')
{
for(int ii=0; ii<n; ii++)
for(int jj=0; jj<m; jj++)
{
if(e[ii][jj]=='H')
addedge(a[i][j],b[ii][jj],1,abs(ii-i)+abs(jj-j));
}
}
}
k--;
for(int i=1; i<=k/2; i++)
{
addedge(0,i,1,0);
}
for(int i=k/2+1; i<=k; i++)
addedge(i,k+1,1,0);
int cost=0;
int ans=MinCostMaxFlow(0,k+1,cost);
cout<<cost<<endl;
}
return 0;
}