题目链接: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;
}