您的位置:首页 > 其它

POJ3169 Layout 差分约束系统[三星]

2015-11-01 15:28 337 查看
题目链接:POJ

CodeVs

由于是英文题目就不再复制题面了~

昨天看CV月赛的题看到这个题,因为Std有个地方看不懂所以自己再做了一下。

首先本题仔细读题后发现求最大值,于是就跑最短路:

然后再仔细读题会发现3个约束条件:

①:两个妹子不和,b-a >= c的情况,将它转化为最短路形式的约束条件就是:a<=b-c(这里我用的我总结的方法,链接:QAQAQAQ)这种情况下是b向a建一条权值为-c的边

②:两个妹子是百合,b-a<=c的情况,将它转换变成了:b<=a+c,即a向b建一条权值为c的边。

③:两个位置可以重合,但我们按从左向右的顺序来的话就是a <= b,即b向a建一条权值为0的边。

这样约束条件都列举了出来,之后再建边就行了,-1的情况是无解的情况,即存在负环,-2的情况是无法约束1到n距离的情况,即再约束系统中没有从1到达n的路径,如果都不是上面两种情况,就输出答案。

网上有篇std是将约束条件①反过来读,就是先读b再读a然后b->a建边……和我的想法其实是一致的QAQ

完整代码:

[code]#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
using namespace std;
typedef long long ll;
const int size = 100010;
const int INF = 1077952576;
struct Edge{int to,dist;}edges[size];
int head[size],next[size],tot;
void build(int f,int t,int d)
{
    edges[++tot].to = t;
    edges[tot].dist = d;
    next[tot] = head[f];
    head[f] = tot;
}
int n,m,k;
int dist[size],cishu[size];
bool vis[size];
deque <int> q;
bool spfa()
{
    memset(dist,64,sizeof(dist));
    q.push_back(1);
    vis[1] = 1;
    dist[1] = 0;
    while(!q.empty())
    {
        int f = q.front();
        q.pop_front();
        vis[f] = 0;
        for(int i = head[f];i;i = next[i])
        {
            int v = edges[i].to;
            if(dist[v] > dist[f] + edges[i].dist)
            {
                dist[v] = dist[f] + edges[i].dist;
                if(!vis[v])
                {
                    cishu[v] ++;
                    if(cishu[v] > n)    return true;
                    vis[v] = 1;
                    if(!q.empty() && dist[v] < dist[q.front()]) q.push_front(v);
                    else q.push_back(v);
                }
            }
        }
    }
    return false;
}
int main()
{
    scanf("%d%d%d",&n,&m,&k);
    for(int i = 1;i <= m;i ++)
    {
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        build(a,b,c);
    }
    for(int i = 1;i <= k;i ++)
    {
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        build(b,a,-c);
    }
    for(int i = 1;i < n;i ++)   build(i+1,i,0);
    if(spfa())  puts("-1");
    else if(dist
 == INF) puts("-2");
    else printf("%d",dist
);
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: