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

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

时间: 2024-10-24 19:10:04

poj 2391Ombrophobic Bovines 【蛮简单的网络流】的相关文章

POJ 2391Ombrophobic Bovines(二分+最短路+网络流之最大流)

题目地址:http://poj.org/problem?id=2391 这个题WA了一晚上,原因是数组开小了,然后又TLE了一天,原因是数组改的过大了....不多说什么了... 思路不难,建图也不难,二分时间,然后把每个田地之间的最短距离用floyd最短路求出来.然后建立一个源点与汇点,将田地拆分成两个点,在距离之内的进行连边,要单向连边.然后将源点与田地相连,权值为每个田地的牛的数目,再把另一边的田地与汇点相连,权值为每个田地最大可避雨的牛的数目.拆开的田地之间权值可以为无穷大. 代码如下:

POJ 2391-Ombrophobic Bovines(网络流_最大流+floyd+二分)

Ombrophobic Bovines Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 15485   Accepted: 3361 Description FJ's cows really hate getting wet so much that the mere thought of getting caught in the rain makes them shake in their hooves. They h

POJ 2391--Ombrophobic Bovines【拆点 &amp;&amp; 二分 &amp;&amp; 最大流dinic &amp;&amp; 经典】

Ombrophobic Bovines Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16460   Accepted: 3593 Description FJ's cows really hate getting wet so much that the mere thought of getting caught in the rain makes them shake in their hooves. They h

POJ 2391 Ombrophobic Bovines (二分,最短路径,网络流sap,dinic,预留推进 )

Ombrophobic Bovines Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14019   Accepted: 3068 Description FJ's cows really hate getting wet so much that the mere thought of getting caught in the rain makes them shake in their hooves. They h

POJ 2455Secret Milking Machine(二分+网络流之最大流)

题目地址:POJ2455 手残真浪费时间啊..又拖到了今天才找出了错误..每晚两道题不知不觉又变回了每晚一道题...sad.. 第一次在isap中忘记调用bfs,第二次则是遍历的时候居然是从1开始遍历的...sad... 这题思路倒是很简单,就是有一个比较坑的地方,就是这里的重边要当两条边来用,以前受最短路什么的影响,直接把慢的删了,很明显不对...这里的两条重边都是可以走的. 建图思路是,将1当作源点,将n当作汇点.右边的地方就连边,注意是无向边.最后判断最大流是否等于道路条数.二分找最小值.

POJ 1698 Alice&#39;s Chance(网络流+构图)

题目链接:http://poj.org/problem?id=1698 题目: Description Alice, a charming girl, have been dreaming of being a movie star for long. Her chances will come now, for several filmmaking companies invite her to play the chief role in their new films. Unfortuna

POJ训练计划3422_Kaka&#39;s Matrix Travels(网络流/费用流)

解题报告 题目传送门 题意: 从n×n的矩阵的左上角走到右下角,每次只能向右和向下走,走到一个格子上加上格子的数,可以走k次.问最大的和是多少. 思路: 建图:每个格子掰成两个点,分别叫"出点","入点", 入点到出点间连一个容量1,费用为格子数的边,以及一个容量∞,费用0的边. 同时,一个格子的"出点"向它右.下的格子的"入点"连边,容量∞,费用0. 源点向(0,0)的入点连一个容量K的边,(N-1,N-1)的出点向汇点连一

POJ 1087 A Plug for UNIX(网络流之最大流)

题目地址:POJ 1087 不知道是谁把这题化为了二分最大匹配的专题里..于是也没多想就按照二分图的模型来建的(虽然当时觉得有点不大对...).后来发现二分最大匹配显然不行..有权值..直接来个最大流多方便..然后一直WA..后来仔细想了想..这根本就不能建二分图啊....这题跟二分图一点关系都没有.... 这题的建图思路是让源点与每一个设备的插座类型连边,让汇点与每一个插座连边.然后用floyd判断该设备能否通过转换转换成可以插的插座上.只要可以转换成的就连边,权值为INF.然后求一次最大流,

POJ 3071 Football(简单 概率DP)

Football 原文链接:http://blog.csdn.net/xuechelingxiao/article/details/38520105 大意:2^n 个球队进行单场淘汰赛,每两只球队之间比赛会有胜负的概率,问最后谁夺冠的概率最大. 思路:简单的概率DP问题,主要是怎么处理哪两个球队比赛的问题. DP方程为 dp[i][j] = ∑(dp[i-1][j]*dp[i-1][k]*p[j][k]); //dp[i][j]表示第 i 轮的时候,第 j 支队伍赢的概率.. 对于其中位运算,可