孤独的小Z (差分约束)

差分约束:

  • 一系列的不等式,看有没有满足条件的解
  • 转化为文字就是 至少多,至多多, 等等字样 要反应过来
  • 比如 a-b>=x, 然后这个可以变化为 b-a<=-x, 用大于还是小于看题目
  • 然后 这个东西 和 图论联系在一起 a-b>=x  相当于 a>=x+b, x就是边权值,如果相等就 2个点相互连接 w=0;
  • 至少>= 就是求最长路,(才能满足条件嘛) 
  • 至多<=, 就是求最短路
  • 不存在解,就是有环. (局部正确是没有问题的)
  • 利用spfa算法

Problem - E - Codeforces

本题就是模板题:

#include <bits/stdc++.h>
using namespace std;
#define ri register int
#define M 200005

int n,m;
struct dian{
    int to,val;
};
vector <dian> p[M];
int T;
int dis[M];
int flag=0;
int vis[M],cnt[M];
queue<int> q;

void dfs(int a)
{
    while(!q.empty()) q.pop();
    q.push(a); 
    while(!q.empty())
    {
         a=q.front();q.pop();
        vis[a]=0;
        for(ri i=0;i<p[a].size();i++)
        {
            int b=p[a][i].to;
            if(dis[b]<dis[a]+p[a][i].val)
            {
                dis[b]=dis[a]+p[a][i].val;
                cnt[b]=cnt[a]+1;
                if(cnt[b]>=n)
                {
                    flag=1;break;
                }
                if(vis[b]==0)
                {
                    q.push(b);
                    vis[b]=1;
                }
            }
            
        }
        if(flag) break;
    }
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    
    cin>>T;
    while(T--)
    {
        cin>>n>>m;
    
        for(ri i=1;i<=n;i++)
        {
            p[i].clear();
            dis[i]=0;
        }
        flag=0;
        for(ri i=1;i<=m;i++)
        {
            int a,b,c,d;
            cin>>a;
            if(a==1)
            {
                cin>>b>>c>>d;
                 dian t;
                 t.to=b;t.val=d;
                 p[c].push_back(t);
            }
            if(a==2)
            {    cin>>b>>c>>d;
                 dian t;
                 t.to=c;t.val=-d;
                 p[b].push_back(t);
            }
            if(a==3)
            {
                    cin>>b>>c;
                 dian t;
                 t.to=c;t.val=0;
                 p[b].push_back(t);
                 t.to=b;t.val=0;
                 p[c].push_back(t);
            }
        }
        for(ri i=1;i<=n;i++)
        {
            vis[i]=0;cnt[i]=0;
        }
        for(ri i=1;i<=n;i++)
        {
            if(dis[i]==0)
            {
                dfs(i);
            }
        }
        if(flag) 
        {
            cout<<-1<<endl;
            continue;
        }
        int ans=0;
        for(ri i=1;i<=n;i++) ans+=dis[i];
        cout<<ans<<endl;
    }
    return 0;
    
    
}
View Code

 

posted @ 2022-07-03 18:11  VxiaohuanV  阅读(26)  评论(0编辑  收藏  举报