# 差分约束系统之Bellman_Ford与Spfa判断负权回路

#include <iostream>
#include <string.h>
#include <stdio.h>

using namespace std;
const int N = 105;
const int INF = 1<<29;

struct Edge
{
int s,t;
int w;
};

Edge edge[N*N];

int dist[N];
int cnt,n,m;

{
edge[cnt].s = u;
edge[cnt].t = v;
edge[cnt].w = w;
cnt++;
}

void Relax(int s,int t,int w)
{
if(dist[t] > dist[s] + w)
dist[t] = dist[s] + w;
}

bool Bellman_Ford(int s)
{
for(int i=0; i<n; i++)
dist[i] = INF;
dist[s] = 0;
for(int i=0; i<n; i++)
for(int j=0; j<cnt; j++)
Relax(edge[j].s,edge[j].t,edge[j].w);
for(int i=0; i<cnt; i++)
if(dist[edge[i].t] > dist[edge[i].s] + edge[i].w)
return true;
return false;
}

int main()
{
char str[5];
while(cin>>n)
{
if(n == 0)  break;
cin>>m;
cnt = 0;
while(m--)
{
int a,b,c;
cin>>a>>b>>str>>c;
if(str[0]=='l')
else
}
if(Bellman_Ford(0))  cout<<"successful conspiracy"<<endl;
else                 cout<<"lamentable kingdom"<<endl;
}
return 0;
}

Bellman_Ford算法的时间复杂度为O(VE)，算法简单，适用范围又广，虽然复杂度稍高，仍不失为一个很实用的算法。

#include <iostream>
#include <string.h>
#include <stdio.h>
#include <queue>

using namespace std;
const int N = 105;
const int INF = 1<<29;

struct Edge
{
int to;
int w;
int next;
};

Edge edge[N*N];

bool vis[N];

int n,m,cnt;
queue<int> Q;

{
edge[cnt].to = v;
edge[cnt].w = w;
}

void Init()
{
cnt = 0;
memset(vis,0,sizeof(vis));
memset(time,0,sizeof(time));
}

bool Spfa(int s)
{
for(int i=0; i<=n+1; i++)
dist[i] = -INF;
dist[s] = 0;
time[s] = 1;
vis[s] = 1;
while(!Q.empty()) Q.pop();
Q.push(s);
while(!Q.empty())
{
int u  =Q.front();
vis[u] = 0;
Q.pop();
{
int v = edge[i].to;
int w = edge[i].w;
if(dist[v] < dist[u] + w)
{
dist[v] = dist[u] + w;
if(!vis[v])
{
vis[v] = 1;
Q.push(v);
time[v]++;
if(time[v] > n)
return false;
}
}
}
}
return true;
}

int main()
{
char str[5];
while(cin>>n)
{
Init();
if(n == 0) break;
cin>>m;
for(int i=0; i<n+1; i++)
while(m--)
{
int a,b,c;
cin>>a>>b>>str>>c;
if(str[0] == 'g')
add(a + b + 1,a,c + 1);
else
add(a,a + b + 1,1 - c);
}
int s = 0;
if(Spfa(s)) cout<<"lamentable kingdom"<<endl;
else        cout<<"successful conspiracy"<<endl;
}
return 0;
}

，然后我们根据这两个不等式建图，然后就转化为最长路径问题。

#include <iostream>
#include <string.h>
#include <stdio.h>
#include <queue>

using namespace std;
const int N = 50005;
const int INF = 1<<30;

struct Edge
{
int to;
int w;
int next;
};

Edge edge[4*N];

bool vis[N];
int cnt,s,t;

queue<int> Q;

void Init()
{
cnt = 0;
memset(vis,0,sizeof(vis));
}

{
edge[cnt].to = v;
edge[cnt].w = w;
}

void Spfa(int s)
{
for(int i=0; i<N; i++)
dist[i] = -INF;
dist[s] = 0;
while(!Q.empty()) Q.pop();
Q.push(s);
vis[s] = 1;
while(!Q.empty())
{
int u = Q.front();
vis[u] = 0;
Q.pop();
{
int v = edge[i].to;
int w = edge[i].w;
if(dist[v] < dist[u] + w)
{
dist[v] = dist[u] + w;
if(!vis[v])
{
vis[v] = 1;
Q.push(v);
}
}
}
}
}

int main()
{
int n;
while(~scanf("%d",&n))
{
Init();
s = INF;
t = -1;
while(n--)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
if(u < s)  s = u;
if(v + 1 > t) t = v + 1;
}
for(int i=s; i<=t; i++)
{