接触了差分约束系统,其实就是最短路。
这个题目题意理解起来有点麻烦,不过其实是很简单的模板题。
注意的点:用spfa时,因为图可能不是联通的,所以要加一个花费为0的超级源点。题目给点限制条件是大于小于,但是差分约束系统是有等号的,对于整数来说只要加一减一就可以。
记录模板
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int maxn=105;
const int maxe=10005;
int head[maxn],cnt=0;
struct Edge{
int to,next;
int w;
}edge[maxe];
void init()
{
memset(head,-1,sizeof(head));
cnt=0;
}
void add(int u,int v,int w)
{
edge[cnt].to=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt++;
}
int dis[maxn],c[maxn],vis[maxn];
int n;
bool spfa(int s)
{
queue<int> que;
memset(dis,0x3f,sizeof(dis));
memset(vis,0,sizeof(vis));
memset(c,0,sizeof(c));
dis[s]=0;
que.push(s);
vis[s]=1;
c[s]++;
while(!que.empty())
{
int u=que.front();
que.pop();
vis[u]=0;
for(int i=head[u];~i;i=edge[i].next)
{
int v=edge[i].to;
int w=edge[i].w;
if(dis[u]+w<dis[v])
{
dis[v]=dis[u]+w;
if(!vis[v])
{
que.push(v);
vis[v]=1;
c[v]++;
if(c[v]>n+1) return false; //因为这里是n+1个点(不包括超级源点
}
}
}
}
return true;
}
int main()
{
int m;
while(cin>>n)
{
if(n==0) break;
cin>>m;
init();
for(int i=0;i<m;i++)
{
int a,b,w;
char ch[5];
scanf("%d%d%s%d",&a,&b,ch,&w);
if(ch[0]=='g') add(b+a,a-1,-w-1);
else add(a-1,b+a,w-1);
}
for(int i=0;i<=n;i++)
add(n+1,i,0);
if(spfa(n+1)) printf("lamentable kingdom\n");
else printf("successful conspiracy\n");
}
return 0;
}