zoukankan      html  css  js  c++  java
  • luogu P2153 [SDOI2009]晨跑

    传送门

    思路

    观察题目,我们可以发现,这个晨跑路线就是增广路,若把每条边的容量定为一,最大流就是周期的最长天数。

    基于最长天数的最短路程,对应的就是最小费用最大流。

    因此根据给的数据来建边即可。

    本题还有一个额外要求,就是每条路不能经过相同的点,而不同的增广路只能保证经过的边没有重复,那怎么办?

    简单,只要将每一个点拆成两个点,连接拆出的两个点的边容量为一,只能过一次,自然保证了一个点不过被经过两次。

    至于起点与终点,只要单独拿出来建容量为inf的边即可。

    代码

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<queue>
    using namespace std;
    const int N=2e5+10;
    int n,m,s,t;
    
    int ver[N],Next[N],head[N],val[N],c[N],tot=1;
    void add(int x,int y,int z,int w)
    {
    	ver[++tot]=y;val[tot]=z;c[tot]=w;Next[tot]=head[x];head[x]=tot;
    	ver[++tot]=x;val[tot]=0;c[tot]=-w;Next[tot]=head[y];head[y]=tot;
    }
    
    int dis[N],vis[N],pre[N],incf[N];
    bool bfs()
    {
    	memset(vis,0,sizeof(vis));
    	memset(dis,0x3f,sizeof(dis));
    	queue<int>q;
    	q.push(s);incf[s]=1e9;dis[s]=0;
    	while(!q.empty())
    	{
    		int u=q.front();q.pop();vis[u]=0;
    		for(int i=head[u];i;i=Next[i])
    		{
    			int v=ver[i];
    			if(dis[v]>dis[u]+c[i]&&val[i])
    			{
    				dis[v]=dis[u]+c[i];
    				incf[v]=min(incf[u],val[i]);
    				pre[v]=i;
    				if(!vis[v]){
    					vis[v]=1;q.push(v);
    				}
    			}
    		}
    	}
    	if(dis[t]>1e9)return 0;
    	return 1;
    }
    
    int maxn,minn;
    void update()
    {
    	int u=t;
    	while(u!=s)
    	{
    		int i=pre[u];
    		val[i]-=incf[t];
    		val[i^1]+=incf[t];
    		u=ver[i^1];
    	}
    	maxn+=incf[t];
    	minn+=incf[t]*dis[t];
    }
    
    int main()
    {
    	scanf("%d%d",&n,&m);
    	s=1;t=n*2;
    	add(1,1+n,1e9,0);
    	add(n,n*2,1e9,0);
    	for(int i=2;i<=n-1;i++)add(i,i+n,1,0);
    	while(m--)
    	{
    		int x,y,z;
    		scanf("%d%d%d",&x,&y,&z);
    		add(x+n,y,1,z);
    	}
    	while(bfs())update();
    	printf("%d %d",maxn,minn);
    	return 0;
    }
    
  • 相关阅读:
    【基础算法】- 全排列
    【基础算法】- 2分查找
    区块链培训
    Static Binding (Early Binding) vs Dynamic Binding (Late Binding)
    test
    No data is deployed on the contract address!
    "throw" is deprecated in favour of "revert()", "require()" and "assert()".
    Variable is declared as a storage pointer. Use an explicit "storage" keyword to silence this warning.
    京都行
    Failed to write genesis block: database already contains an incompatible
  • 原文地址:https://www.cnblogs.com/luotao0034/p/14441869.html
Copyright © 2011-2022 走看看