您的位置:首页 > 其它

bzoj 2019: [Usaco2009 Nov]找工作 最长路

2017-08-16 15:44 351 查看
题目链接

显然就是找一个最长路

两个城市有路径就建一个权值为d的边

如果有航线就建一个权值为d-z的边

边的权值表示经过这个边可以获得多少钱

最后从起点开始跑最长路就好,答案对于每个点取max

有正环就是无解,跟判负环一样

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>

#define inf 999999999

using namespace std;

struct node{
int to,len;
};

int n,m1,m2,d,s;
vector<node>v[1010];
int dis[1010];
int num[1010];
bool vis[1010];
queue<int>q;
bool f=true;

void link(int x,int y,int z){
node t;
t.to=y;
t.len=z;
v[x].push_back(t);
}

void spfa(){
for(int i=1; i<=n; i++)dis[i]=0;
dis[s]=d;
vis[s]=true;
num[s]=1;
q.push(s);
while(!q.empty()){
int t=q.front();
q.pop();
for(int i=0; i<v[t].size(); i++){
int to=v[t][i].to;
int len=v[t][i].len;
if(dis[to]<dis[t]+len){
dis[to]=dis[t]+len;
if(!vis[to]){
if(num[to]==n){
f=false;
return;
}
vis[to]=true;
q.push(to);
num[to]++;
}
}
}
vis[t]=false;
}
}

int main(){
scanf("%d%d%d%d%d",&d,&m1,&n,&m2,&s);
for(int i=0; i<m1; i++){
int x,y;
scanf("%d%d",&x,&y);
link(x,y,d);
}
for(int i=0; i<m2; i++){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
link(x,y,d-z);
}
spfa();
if(!f)printf("-1\n");
else{
int Max=0;
for(int i=1; i<=n; i++)Max=max(Max,dis[i]);
printf("%d\n",Max);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: