zoukankan      html  css  js  c++  java
  • jzoj 1287. 躲雨

    Question

    给你nn个点,mm条边。每个点都有一个容量限制和当前存在的量,每条边都有一个所需时间。
    求当所有点的量都符合限制是的最少需要时间。

    Solution

    我们先用floydfloyd求出两两点之间的最短时间。
    然后二分答案,对于时间<=mid<=mid的边就加,而后跑一遍网络流看看是否全都能流完即可。
    加边具体操作:
    设起始点为SS,终点为TT
    1.SS向第ii个点连一条a[i]a[i]的边
    2.第n+in+i个点向TT连一条b[i]b[i]的边
    3.对于时间<=mid<=mid的原边(i,n+i)(i,n+i),第ii个点向第n+in+i个点连一条a[i]a[i]的边

    Code

    #include<cstdio>
    #include<cstring>
    #define N 210
    #define ll long long
    using namespace std;
    struct node{int v,fr,flow;}e[N*N*20];
    int n,m,a[N],b[N],tail[N<<1],cnt;
    int S=0,T,num=0,dis[N<<1],gap[N<<1];
    ll l=0,r=0,mid,ans=-1,fl[N][N];
    
    inline int read()
    {
    	int x=0; char c=getchar();
    	while (c<'0' || c>'9') c=getchar();
    	while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x;
    }
    
    inline ll min(ll x,ll y) {return x<y ? x:y;}
    
    inline void add(int u,int v,int flow)
    {
    	e[++cnt]=(node){v,tail[u],flow}; tail[u]=cnt;
    	e[++cnt]=(node){u,tail[v],0}; tail[v]=cnt;
    }
    
    int dfs(int x,int hav)
    {
    	if (x==T) return hav;
    	int gone=0;
    	for (int p=tail[x],v,can;p;p=e[p].fr)
    	{
    		v=e[p].v;
    		if (dis[v]+1!=dis[x] || !e[p].flow) continue;
    		can=dfs(v,min(hav-gone,e[p].flow));
    		e[p].flow-=can,e[p^1].flow+=can,gone+=can;
    		if (gone==hav) return gone;
    	}
    	gap[dis[x]]--;
    	if (!gap[dis[x]]) dis[S]=T;
    	gap[++dis[x]]++;
    	return gone;
    }
    
    bool check(ll mid)
    {
    	cnt=1;
    	memset(tail,0,sizeof(tail));
    	memset(dis,0,sizeof(dis));
    	memset(gap,0,sizeof(gap));
    	for (int i=1;i<=n;i++)
    		for (int j=i+1;j<=n;j++)
    			if (fl[i][j]<=mid) 
    				add(i,n+j,a[i]),add(j,n+i,a[j]);
    	for (int i=1;i<=n;i++)
    		add(S,i,a[i]),add(n+i,T,b[i]),add(i,n+i,a[i]);
    	int s=0;
    	while (dis[S]<T) s+=dfs(S,num);
    	if (s==num) return 1;
    	else return 0;
    }
    
    int main()
    {
    	freopen("rain.in","r",stdin);
    	freopen("rain.out","w",stdout);
    	n=read(),m=read();T=n+n+1;
    	for (int i=1;i<=n;i++)
    		a[i]=read(),b[i]=read(),num+=a[i];
    	memset(fl,60,sizeof(fl));
    	for (int i=1,u,v,lg;i<=m;i++)
    	{
    		u=read(),v=read(),lg=read();r+=lg;
    		fl[v][u]=fl[u][v]=min(fl[u][v],lg);
    	}
    	for (int k=1;k<=n;k++)
    		for (int i=1;i<=n;i++)
    			for (int j=1;j<=n;j++)
    				fl[j][i]=fl[i][j]=min(fl[i][j],fl[i][k]+fl[k][j]);
    	while (l<=r)
    	{
    		mid=l+r>>1;
    		if (check(mid)) ans=mid,r=mid-1;
    		else l=mid+1;
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    
    转载需注明出处。
  • 相关阅读:
    springboot springcloud zuul 过滤器
    springboot springcloud eureka 熔断器
    javaweb servlet filter
    maven nexus 搭建私服(二)
    springboot springcloud zuul 网关入门
    springboot springcloud 配置中心
    springboot springcloud eureka 入门
    java rabbitmq
    java jvm调优
    maven nexus 搭建私服(一)
  • 原文地址:https://www.cnblogs.com/jz929/p/11817518.html
Copyright © 2011-2022 走看看