网络流 最小费用最大流

网络流裸题 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;
}

POJ 1087

#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;
}

POJ 2195

#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;
}

猜你喜欢

转载自blog.csdn.net/flyzer/article/details/81271073