bzoj3436

差分约束系统

按题目建边就行了,大于等于号是最长路,小于等于号是最短路,边由减号后面连向减号前面,边权是不等号后面的常数项

这里跑最长路,用dfs版spfa跑

#include<bits/stdc++.h>
using namespace std;
const int N = 10010;
struct edge {
    int nxt, to, w;
} e[N << 4];
int n, m, cnt = 1;
int head[N], vis[N], d[N];
bool dfs(int u)
{
    vis[u] = 1;
    for(int i = head[u]; i; i = e[i].nxt) if(d[e[i].to] < d[u] + e[i].w)
    {
        if(vis[e[i].to]) return true;
        d[e[i].to] = d[u] + e[i].w;
        if(dfs(e[i].to)) return true;
    }
    vis[u] = 0;
    return false;
}
void link(int u, int v, int w)
{
    e[++cnt].nxt = head[u];
    head[u] = cnt;
    e[cnt].to = v;
    e[cnt].w = w;
}
int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= m; ++i)
    {
        int opt, u, v, w;
        scanf("%d%d%d", &opt, &u, &v);
        if(opt == 1)
        {
            scanf("%d", &w);
            link(v, u, w);
        }
        if(opt == 2)
        {
            scanf("%d", &w);
            link(u, v, -w);
        }
        if(opt == 3)
        {
            link(u, v, 0);
            link(v, u, 0);
        }
    }
    memset(d, -0x3f3f, sizeof(d));
    for(int i = 1; i <= n; ++i) 
    {
        d[i] = 0;
        if(dfs(i))
        { 
            puts("No");
            return 0;
        }
    }
    puts("Yes");
    return 0;
}
 
View Code
原文地址:https://www.cnblogs.com/19992147orz/p/7462665.html