zoukankan      html  css  js  c++  java
  • poj 2391 Ombrophobic Bovines【最大流】

    我%……&(……,调了一下午,最后发现P赋值1e5能过,赋值1e6就会TLE致死。改了一下午加一晚上然而这是为什么???
    一种常见的建图套路,首先二分答案,注意上界要取大一点,1e9是不行的。然后问题变为判定,首先弗洛伊德求出点两两之间的最短距离。每次建图时把点拆成两个,然后s向所有的i连容量为a[i]的边,所有i+n向t连容量为b[i]的边。对于原图中的一条边(u,v),如果长度小于等于当前二分的mid的,连接u和v+n,容量为inf。(因为可以同时走)
    记得来long long

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    const long long P=100005,inf=1e12;
    long long n,m,h[P],cnt=1,a[P],b[P],s,t,sum,le[P],d[233][233];
    struct qwe
    {
    	long long ne,to,va;
    }e[P];
    long long read()
    {
    	long long r=0,f=1;
    	char p=getchar();
    	while(p>'9'||p<'0')
    	{
    		if(p=='-')
    			f=-1;
    		p=getchar();
    	}
    	while(p>='0'&&p<='9')
    	{
    		r=r*10+p-48;
    		p=getchar();
    	}
    	return r*f;
    }
    void add(long long u,long long v,long long w)
    {
    	cnt++;
    	e[cnt].ne=h[u];
    	e[cnt].to=v;
    	e[cnt].va=w;
    	h[u]=cnt;
    }
    void ins(long long u,long long v,long long w)
    {
    	add(u,v,w);
    	add(v,u,0);
    }
    bool bfs()
    {
    	queue<long long>q;
    	memset(le,0,sizeof(le));
    	le[s]=1;
    	q.push(s);
    	while(!q.empty())
    	{
    		long long u=q.front();
    		q.pop();
    		for(long long i=h[u];i;i=e[i].ne)
    			if(e[i].va>0&&!le[e[i].to])
    			{
    				le[e[i].to]=le[u]+1;
    				q.push(e[i].to);
    			}
    	}
    	return le[t];
    }
    long long dfs(long long u,long long f)
    {
    	if(u==t||!f)
    		return f;
    	long long us=0;
    	for(long long i=h[u];i&&us<f;i=e[i].ne)
    		if(e[i].va>0&&le[e[i].to]==le[u]+1)
    		{
    			long long t=dfs(e[i].to,min(e[i].va,f-us));
    			e[i].va-=t;
    			e[i^1].va+=t;
    			us+=t;
    		}
    	if(!us)
    		le[u]=0;
    	return us;
    }
    long long dinic()
    {
    	long long re=0;
    	while(bfs())
    		re+=dfs(s,inf);
    	return re;
    }
    bool ok(long long p)
    {
    	memset(h,0,sizeof(h));
    	cnt=1;
    	for(long long i=1;i<=n;i++)
    		ins(s,i,a[i]),ins(i+n,t,b[i]);
    	for(long long i=1;i<=n;i++)
    		for(long long j=1;j<=n;j++)
    			if(d[i][j]<=p)
    				ins(i,j+n,inf);
    	return dinic()==sum;
    }
    int main()
    {
    	scanf("%d%d",&n,&m);
    	s=0,t=2*n+1;
    	for(long long i=1;i<=n;i++)
    	{
    		scanf("%d%d",&a[i],&b[i]);
    		sum+=a[i];
    	}
    	for(long long i=1;i<=n;i++)
    		for(long long j=1;j<=n;j++)
    			d[i][j]=inf;
    	for(long long i=1;i<=n;i++)
    		d[i][i]=0;
    	for(long long i=1;i<=m;i++)
    	{
    		long long x,y;
    		long long z;
    		scanf("%d%d%lld",&x,&y,&z);
    		d[x][y]=d[y][x]=min(d[x][y],z);
    	}
    	for(long long k=1;k<=n;k++)
    		for(long long i=1;i<=n;i++)
    			for(long long j=1;j<=n;j++)
    				if(d[i][j]>d[i][k]+d[k][j])
    					d[i][j]=d[i][k]+d[k][j];
    	long long l=-1,r=inf;
    	while(r-l>1)
    	{
    		long long mid=(l+r)>>1;
    		if(ok(mid))
    			r=mid;
    		else
    			l=mid;
    	}
    	printf("%lld",r==inf?-1:r);
    	return 0;
    }
    
  • 相关阅读:
    DS博客作业03--树
    DS博客作业02--栈和队列
    数据结构——线性表
    结构体
    C博客作业05--指针
    C语言博客作业04--数组
    面向对象设计大作业第二阶段:图书馆系统
    Java程序设计-有理数类的设计
    DS博客作业05-查找
    DS博客作业04-图
  • 原文地址:https://www.cnblogs.com/lokiii/p/8379570.html
Copyright © 2011-2022 走看看