这图如果是不连通的,SPFA是会出问题的,所以可以增加一个V0的虚拟节点。
注意,题目中是>和<,要转换成>=和《=才能应用差分约束,由于是整数,是很好转换的。
得到差分约束方程:s[si+ni]-s[si-1]>=cost+1
s[si+ni]-s[si-1]<=cost-1
在做SPFA时,如果存在负环则return false,表明不能满足所有的约束方程,如果不出现负权环
则可以找到这样的序列。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int N = 105;
const int INF = 0x7f7f7f7f;
struct Edge
{
int to,dis;
Edge *next;
};
Edge * adj[N];
Edge edges[N*2];
int n,m;
int dis[N];
bool vis[N];
int vCnt[N];
char str[10];
int cnt;
void addEdge(int s,int e,int w)
{
Edge *ptr = &edges[cnt++];
ptr->to = e;
ptr->dis = w;
ptr->next = adj[s];
adj[s] = ptr;
}
int maxt;
bool spfa()
{
queue <int> Q;
memset(vis,false,sizeof(vis));
memset(vCnt,0,sizeof(vCnt));
memset(dis,127,sizeof(dis));
Q.push(0);
vCnt[0] = 1;
dis[0] = 0;
while(!Q.empty())
{
int u =Q.front(); Q.pop();
vis[u] = false;
for(Edge *ptr=adj[u];ptr;ptr=ptr->next)
{
int cost = ptr->dis;
int v = ptr->to;
if(dis[v]>dis[u]+cost)
{
dis[v] = dis[u] + cost;
if(!vis[v])
{
Q.push(v);
vCnt[v]++;
if(vCnt[v]>=n+1)
{
return false;
}
vis[v] = true;
}
}
}
}
return true;
}
int main()
{
while(scanf("%d",&n)!=EOF&&n!=0)
{
memset(adj,0,sizeof(adj));
cnt = 0;
maxt = 0;
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
int a,b,cost;
scanf("%d%d%s%d",&a,&b,str,&cost);
a++;
b = b+a;
if(strcmp(str,"gt")==0)
{
addEdge(b,a-1,-(cost+1));
}
else
{
addEdge(a-1,b,cost-1);
}
}
for(int i=1;i<=n;i++)
{
addEdge(0,i,0);//增加虚拟节点
}
spfa() ?printf("lamentable kingdom\n") : printf("successful conspiracy\n") ;
}
return 0;
}
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int N = 105;
const int INF = 0x7f7f7f7f;
struct Edge
{
int to,dis;
Edge *next;
};
Edge * adj[N];
Edge edges[N*2];
int n,m;
int dis[N];
bool vis[N];
int vCnt[N];
char str[10];
int cnt;
void addEdge(int s,int e,int w)
{
Edge *ptr = &edges[cnt++];
ptr->to = e;
ptr->dis = w;
ptr->next = adj[s];
adj[s] = ptr;
}
int maxt;
bool spfa()
{
queue <int> Q;
memset(vis,false,sizeof(vis));
memset(vCnt,0,sizeof(vCnt));
memset(dis,127,sizeof(dis));
Q.push(0);
vCnt[0] = 1;
dis[0] = 0;
while(!Q.empty())
{
int u =Q.front(); Q.pop();
vis[u] = false;
for(Edge *ptr=adj[u];ptr;ptr=ptr->next)
{
int cost = ptr->dis;
int v = ptr->to;
if(dis[v]>dis[u]+cost)
{
dis[v] = dis[u] + cost;
if(!vis[v])
{
Q.push(v);
vCnt[v]++;
if(vCnt[v]>=n+1)
{
return false;
}
vis[v] = true;
}
}
}
}
return true;
}
int main()
{
while(scanf("%d",&n)!=EOF&&n!=0)
{
memset(adj,0,sizeof(adj));
cnt = 0;
maxt = 0;
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
int a,b,cost;
scanf("%d%d%s%d",&a,&b,str,&cost);
a++;
b = b+a;
if(strcmp(str,"gt")==0)
{
addEdge(b,a-1,-(cost+1));
}
else
{
addEdge(a-1,b,cost-1);
}
}
for(int i=1;i<=n;i++)
{
addEdge(0,i,0);//增加虚拟节点
}
spfa() ?printf("lamentable kingdom\n") : printf("successful conspiracy\n") ;
}
return 0;
}