poj 1364 King(hud 1531)

本文提供了一种使用SPFA算法解决POJ 1364问题的方法,通过构建图并判断是否存在负环来确定给定条件下是否能够构造出满足一系列不等式的数列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:http://poj.org/problem?id=1364

题意:有n个未知数的序列,x1到xn,现在给你一些关系,这个序列从a开始b项的和与k的关系,大于和小于的关系,问有没有满足条件的序列

思路:设Sx为前x-1项和,所以xi+....xj == S(j+1) - Si,于是有了S(j+1) - Si与k的大小关系;为了保证这是一个连通图,加一个源点S,连接其他点,权值为0

然后跑一遍spfa看看是否有解(判断是否有负环)


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>

using namespace std;

const int inf = 1e9 + 7;
const int maxn = 1010;
int n, m, cnt;
int dis[maxn];
int mark[maxn];
int head[maxn];
bool vis[maxn];
struct P
{
    int to;
    int cost;
    int next;
}edge[maxn];
void add(int u, int v, int cost)
{
    edge[cnt].to = v;
    edge[cnt].cost = cost;
    edge[cnt].next = head[u];
    head[u] = cnt++;
}
bool spfa(int s = 0)
{
        memset(vis, 0, sizeof(vis));
        memset(mark, 0, sizeof(mark));
        for(int i = 0; i < maxn; i++) dis[i] = inf;
        dis[s] = 0;
        queue<int> Q;
        Q.push(s);
        vis[s] = 1;
        mark[s]++;
        while(!Q.empty())
        {
            int cur = Q.front(); Q.pop();
            vis[cur] = 0;
            if(mark[cur] > n + 1)//因为加了一个源点,所以判断n + 1
                return false;
            for(int i = head[cur]; i != -1; i = edge[i].next )
            {
                int tmp = edge[i].to;
                int cost = edge[i].cost;
                if(dis[tmp] > dis[cur] + cost)
                {
                    dis[tmp] = dis[cur] + cost;
                    if(!vis[tmp])
                    {
                        Q.push(tmp);
                        vis[tmp] = 1;
                        mark[tmp]++;
                    }
                }
            }
        }
        return true;
}
int main()
{
    while(cin >> n, n)
    {
        cin >> m;
        memset(head, -1, sizeof(head));
        for(int i = 0; i < m; i++)
        {
            int x, y, z;
            string s;
            cin >> x >> y >> s >> z;
            if(s == "gt")
            {
                add(x + y + 1, x, -z - 1 );
            }
            else
            {
                add(x, x + y + 1, z - 1);
            }
        }
        for(int i = 1; i <= 1 + n; i++)
        {
            add(0, i, 0);
        }
        if(!spfa())
        {
            cout << "successful conspiracy" << endl;
        }
        else
        {
            cout << "lamentable kingdom" << endl;
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值