zoukankan      html  css  js  c++  java
  • 差分约束Layout

    题目

    思路

    很明显的差分约束板子

    • 如果需要求的是两个变量差的最大值,那么需要将所有不等式转变成<=的形式,建图后求最短路;
    • 如果需要求的是两个变量差的最小值,那么需要将所有不等式转化成>=,建图后求最长路。
      本题需要建超级原点使图联通,判掉不合法情况
    • 图中有负环不能到达

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1000+10;
    const int maxm=5000*10+10;
    int n,m,k;
    int head[maxn],ver[maxm],edge[maxm],Next[maxm],tot;
    void add(int x,int y,int z){
    	ver[++tot]=y,edge[tot]=z,Next[tot]=head[x],head[x]=tot;
    }
    int dis[maxn];
    bool vis[maxn];
    bool flag=0;
    int cnt[maxn];
    queue<int>q;
    int spfa(int x){
    	memset(dis,0x3f,sizeof(dis));
    	memset(vis,0,sizeof(vis));
    	dis[x]=0;vis[x]=1;q.push(x);cnt[x]++;
    	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]+edge[i]){
    				dis[v]=dis[u]+edge[i];
    				if(!vis[v]){
    					cnt[v]++;
    					if(cnt[v]>n+1)return -1;
    					vis[v]=1;
    					q.push(v);
    				}
    			}
    		}
    	}
    	if(dis[n]==0x3f3f3f3f)return -2;
    	return dis[n];
    }
    int main(){
    	scanf("%d%d%d",&n,&m,&k);
    	for(int i=1,x,y,z;i<=m;i++){
    		scanf("%d%d%d",&x,&y,&z);
    		if(x>y)swap(x,y);
    		add(x,y,z);
    	}
    	for(int i=1,x,y,z;i<=k;i++){
    		scanf("%d%d%d",&x,&y,&z);
    		if(x>y)swap(x,y);
    		add(y,x,-z);
    	}
    	for(int i=1;i<=n;i++){
    		add(0,i,0);
    	}
    	for(int i=1;i<n;i++){
    		add(i+1,i,0);
    	}
    	if(spfa(0)==-1){
    		printf("-1
    ");
    		return 0;
    	}
    	printf("%d
    ",spfa(1));
    }
     
    
    
  • 相关阅读:
    jedis scan实现keys功能
    java简单实现一个阻塞式线程池
    Swift运算符
    数组的使用(1)
    Linux 常用命令
    Task02:基础查询与排序
    Task01:初识数据库
    摩尔投票法
    面向对象暑期课程总结
    xpath+requests+peewee——CSDN论坛全方位爬虫
  • 原文地址:https://www.cnblogs.com/soda-ma/p/13324935.html
Copyright © 2011-2022 走看看