您的位置:首页 > 其它

POJ 3169 Layout ---差分约束 + 最短路 + 含负边处理

2016-07-04 20:59 357 查看
题意:n头牛编号为1到n,按照编号的顺序排成一列,每两头牛的之间的距离
>= 0。这些牛的距离存在着一些约束关系:1.有ml组(u, v, w)的约束关系,表示牛[u]和牛[v]之间的距离必须 <= w。2.有md组(u, v, w)的约束关系,表示牛[u]和牛[v]之间的距离必须 >= w。问如果这n头无法排成队伍,则输出-1,如果牛[1]和牛
的距离可以无限远,则输出-2,否则则输出牛[1]和牛
之间的最大距离。


分析:采用SPFA算法求最短路+差分约束



样例:



Sample Input
4 2 1
1 3 10
2 4 20
2 3 3


Sample Output
27

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <cstring>
#include <string>
#define INF 0x3f3f3f3f
using namespace std;
const int MAXN = 1005;
const int E = 20005;

int n,ml,md;
int dist[MAXN],cnt[MAXN],p[E],h[MAXN],nxt[E],cost[E];
bool vis[MAXN];
int e;
void add(int u,int v,int w)
{
p[e] = v;
cost[e] = w;
nxt[e] = h[u];
h[u] = e++;

}
void init()
{
e=0;
int u,v,w;int i;
cin >> n>> ml >> md;
memset(h,-1,sizeof(h));
for(i=1;i<=n;i++)
{
dist[i] = INF;
}
for(i=1;i<=ml;i++)
{
cin >> u >> v >> w;
add(u,v,w);
}
for(i=1;i<=md;i++)
{
cin >> u >> v >> w;
add(v,u,-w);
}

for(int i = 2;i<=n;i++)//di <= di+1 + 0
{
add(i,i-1,0);
}
}
bool relax(int u,int v,int w)
{
if(dist[v]>dist[u]+w)
{
dist[v] = dist[u]+w;
return true;
}
return false;

}
int SPFA(int src,int n)
{
memset(vis,false,sizeof(vis));
memset(cnt,0,sizeof(cnt));
dist[src] = 0;
queue<int> Q;
Q.push(src);
vis[src] = true;
++cnt[src];
int i=0;
while(!Q.empty())
{
int u,v;
u = Q.front();
Q.pop();
vis[u] = false;
for(i=h[u];i!=-1;i=nxt[i])
{
v=p[i];
if(relax(u,v,cost[i])&&!vis[v])
{
Q.push(v);
vis[v] = true;
if(++cnt[v]>=n)
return -1;
}
}
}
if(dist
== INF)
return -2;
return dist
;
}

int main()
{
init();
cout<< SPFA(1,n)<< endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: