首页 > 代码库 > poj 2391Ombrophobic Bovines 【蛮简单的网络流】

poj 2391Ombrophobic Bovines 【蛮简单的网络流】

。。。第一个网络流的题目

牛淋雨什么的,建图,用模板之

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
using namespace std;
long long F,P;
long long cowsum;
const int MAX=555;
long long tttt=(1<<31)-1;
const long long INF=tttt*tttt;
long long dis[MAX][MAX];
long long cownum[MAX];
long long sheld[MAX];
//SAP最大流模版

const long long MAXN=1111;//点数的最大值
const long long MAXM=222222;//边数的最大值

struct Node
{
    long long from,to,next;
    long long cap;
}edge[MAXM];
long long tol;
long long head[MAXN];
long long dep[MAXN];
long long gap[MAXN];//gap[x]=y :说明残留网络中dep[i]==x的个数为y

long long n;//n是总的点的个数,包括源点和汇点

void init()
{
    tol=0;
    memset(head,-1,sizeof(head));
}

void addedge(long long u,long long v,long long w)
{
    edge[tol].from=u;
    edge[tol].to=v;
    edge[tol].cap=w;
    edge[tol].next=head[u];
    head[u]=tol++;
    edge[tol].from=v;
    edge[tol].to=u;
    edge[tol].cap=0;
    edge[tol].next=head[v];
    head[v]=tol++;
}
void BFS(long long start,long long end)
{
    memset(dep,-1,sizeof(dep));
    memset(gap,0,sizeof(gap));
    gap[0]=1;
    long long que[MAXN];
    long long front,rear;
    front=rear=0;
    dep[end]=0;
    que[rear++]=end;
    while(front!=rear)
    {
        long long u=que[front++];
        if(front==MAXN)front=0;
        for(long long i=head[u];i!=-1;i=edge[i].next)
        {
            long long v=edge[i].to;
            if(dep[v]!=-1)continue;
            que[rear++]=v;
            if(rear==MAXN)rear=0;
            dep[v]=dep[u]+1;
            ++gap[dep[v]];
        }
    }
}
long long SAP(long long start,long long end)
{
    long long res=0;
    BFS(start,end);
    long long cur[MAXN];
    long long S[MAXN];
    long long top=0;
    memcpy(cur,head,sizeof(head));
    long long u=start;
    long long i;
    while(dep[start]<n)
    {
        if(u==end)
        {
            long long temp=INF;
            long long inser;
            for(i=0;i<top;i++)
               if(temp>edge[S[i]].cap)
               {
                   temp=edge[S[i]].cap;
                   inser=i;
               }
            for(i=0;i<top;i++)
            {
                edge[S[i]].cap-=temp;
                edge[S[i]^1].cap+=temp;
            }
            res+=temp;
            top=inser;
            u=edge[S[top]].from;
        }
        if(u!=end&&gap[dep[u]-1]==0)//出现断层,无增广路
          break;
        for(i=cur[u];i!=-1;i=edge[i].next)
           if(edge[i].cap!=0&&dep[u]==dep[edge[i].to]+1)
             break;
        if(i!=-1)
        {
            cur[u]=i;
            S[top++]=i;
            u=edge[i].to;
        }
        else
        {
            long long min=n;
            for(i=head[u];i!=-1;i=edge[i].next)
            {
                if(edge[i].cap==0)continue;
                if(min>dep[edge[i].to])
                {
                    min=dep[edge[i].to];
                    cur[u]=i;
                }
            }
            --gap[dep[u]];
            dep[u]=min+1;
            ++gap[dep[u]];
            if(u!=start)u=edge[S[--top]].from;
        }
    }
    return res;
}
void input()
{
    scanf("%lld%lld",&F,&P);
	n=F*2+2;
	for(long long i=1;i<=F;i++)
    {
        for(long long j=1;j<=F;j++)
        {
            dis[i][j]=INF;
        }
        dis[i][i]=0;
    }
	for(long long i=1;i<=F;i++)
	{
		long long a,b;scanf("%lld%lld",&a,&b);
		cownum[i]=a;sheld[i]=b;
		cowsum+=a;
	}
	for(long long i=1;i<=P;i++)
	{
		long long u,v,len;scanf("%lld%lld%lld",&u,&v,&len);
		if(dis[u][v]>len)
		{
			dis[v][u]=dis[u][v]=len;
		}
	}
}
void floyd()
{
	for(long long k=1;k<=F;k++)
	{
		for(long long i=1;i<=F;i++)
		{
			for(long long j=1;j<=F;j++)
			{
				if(dis[i][j]>dis[i][k]+dis[k][j])
					dis[i][j]=dis[i][k]+dis[k][j];
			}
		}
	}
}
void makemap(long long maxedge)
{
	for(long long i=1;i<=F;i++)
	{
		for(long long j=1;j<=F;j++)
		{
			if(dis[i][j]<=maxedge)
			{
				addedge(i,j+F,INF);
			}
		}
	}
	for(long long i=1;i<=F;i++)
	{
		addedge(0,i,cownum[i]);
	}
	for(long long i=1;i<=F;i++)
	{
		addedge(i+F,2*F+1,sheld[i]);
	}
}

int main()
{
	#ifndef ONLINE_JUDGE
		freopen("G:/1.txt","r",stdin);
		freopen("G:/2.txt","w",stdout);
	#endif
	input();
	floyd();
	long long ans;
	long long L=0,R=0,mid=0;
	for(long long i=1;i<=F;i++)
	{
		for(long long j=1;j<=F;j++)
		{
		    if(dis[i][j]<INF)
                R=max(R,dis[i][j]);
		}
	}
	R+=10;mid=(L+R)>>1;
	long long ANS=-1;
	while(L<R)
	{
		init();
		makemap(mid);
		ans=SAP(0,2*F+1);
		if(ans>=cowsum)
        {
			ANS=R=mid;
			mid=(L+R)>>1;
        }
		else
        {
			L=mid+1;
			mid=(L+R)>>1;
        }
	}
	printf("%lld\n",ANS);
}