zoukankan      html  css  js  c++  java
  • bzoj 1738 [Usaco2005 mar]Ombrophobic Bovines 发抖的牛 最大流+二分

    题目要求所有牛都去避雨的最长时间最小。

    显然需要二分 二分之后考虑如何判定。

    显然每头牛都可以去某个地方 但是前提是最短路径<=mid.

    依靠二分出来的东西建图。可以发现这是一个匹配问题 dinic即可。

    注意数组要开两倍 因为要拆点 我开小了wa了两发才意识过来。

    const int MAXN=410;
    int n,m,S,len,T,L,R,ans;
    ll a[MAXN][MAXN];
    int c[MAXN],cc[MAXN],cur[MAXN],vis[MAXN],q[MAXN];
    int lin[MAXN],ver[MAXN*MAXN<<1],nex[MAXN*MAXN<<1],e[MAXN*MAXN<<1];
    inline void add(int x,int y,int z)
    {
    	ver[++len]=y;nex[len]=lin[x];lin[x]=len;e[len]=z;
    	ver[++len]=x;nex[len]=lin[y];lin[y]=len;e[len]=0;
    }
    inline int dinic(int x,int flow)
    {
    	if(x==T)return flow;
    	int res=flow,k;
    	for(int i=cur[x];i&&res;i=nex[i])
    	{
    		int tn=ver[i];cur[x]=i;
    		if(vis[tn]==vis[x]+1&&e[i])
    		{
    			k=dinic(tn,min(e[i],res));
    			if(!k){vis[tn]=0;continue;}
    			e[i]-=k;e[i^1]+=k;res-=k;
    		}
    	}
    	return flow-res;
    }
    inline int bfs()
    {
    	rep(1,T,i)vis[i]=0,cur[i]=lin[i];
    	L=R=0;q[++R]=S;vis[S]=1;
    	while(++L<=R)
    	{
    		int x=q[L];
    		go(x)
    		{
    			if(vis[tn]||!e[i])continue;
    			vis[tn]=vis[x]+1;
    			q[++R]=tn;
    			if(tn==T)return 1;
    		}
    	}
    	return 0;
    }
    inline int check(ll x)
    {
    	len=1;
    	memset(lin,0,sizeof(lin));
    	rep(1,n,i)
    	{
    		rep(1,n,j)if(a[i][j]<=x)add(i,j+n,INF);
    		add(S,i,c[i]);add(i+n,T,cc[i]);
    	}
    	int flow,sum=0;
    	while(bfs())while((flow=dinic(S,INF)))sum+=flow;
    	//cout<<sum<<endl;
    	return sum>=ans;
    }
    int main()
    {
    	freopen("1.in","r",stdin);
    	get(n);get(m);int cnt1=0;S=n<<1|1;T=S+1;
    	rep(1,n,i)get(c[i]),cc[i]=read(),ans+=c[i],cnt1+=cc[i];
    	if(ans>cnt1){puts("-1");return 0;}
    	rep(1,n,i)rep(1,i,j)if(i!=j)a[j][i]=a[i][j]=P;
    	rep(1,m,i)
    	{
    		int get(x);int get(y);int get(z);
    		a[x][y]=a[y][x]=min(a[x][y],(ll)z);
    	}
    	rep(1,n,k)rep(1,n,i)rep(1,i,j)a[j][i]=a[i][j]=min(a[i][j],a[i][k]+a[k][j]);
    	ll l=0,r=0;
    	rep(1,n,i)rep(1,i,j)if(a[i][j]!=P)r=max(r,a[i][j]);
    	if(!check(r)){puts("-1");return 0;}
    	while(l<r)
    	{
    		ll mid=(l+r)>>1;
    		if(check(mid))r=mid;
    		else l=mid+1;
    	}
    	putl(l);return 0;
    }
    
  • 相关阅读:
    BZOJ3631 [JLOI2014] 松鼠的新家
    HDU
    HDU
    HDU
    二分图求最大独立集模板
    HDU
    HDU
    HDU
    Codeforces 1197F Coloring Game 矩阵快速幂 (看题解)
    HDU
  • 原文地址:https://www.cnblogs.com/chdy/p/12642961.html
Copyright © 2011-2022 走看看