您的位置:首页 > Web前端

USACO2014FebruaryGold Roadblock

2016-12-28 21:39 246 查看
【分析】

首先我们考虑到,必定在最短路的边进行修改答案才会改变,那我们先跑两遍dijkstra,再枚举边,如果是最短路上的,就改掉,然后跑dijkstra。

我使用vector的,所以还是有点慢。

【代码】

#define M 25005
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define oo 1000000000
using namespace std;
struct node{
int to,v;
bool operator<(const node &a)const{return v>a.v;}
};
priority_queue<node>Q;
vector<node>edge[M];
int dis[4][M],n,m;
bool mk[M];
void Dij(int x,int t,int f){
int i;
for(i=1;i<=n;i++)dis[f][i]=oo,mk[i]=0;
while(!Q.empty())Q.pop();
Q.push((node){x,0});
dis[f][x]=0;
while(!Q.empty()){
node tmp;
tmp=Q.top();
Q.pop();
int k=tmp.to;
if(mk[k])continue;
if(k==t)return;
mk[k]=1;
for(i=0;i<edge[k].size();i++){
node nxt=edge[k][i];
int y=nxt.to;
if(mk[y])continue;
int v=nxt.v;
if(dis[f][y]>dis[f][k]+v){
dis[f][y]=dis[f][k]+v;
Q.push((node){y,dis[f][y]});
}
}
}
}
int main(){
int i,j;
scanf("%d %d",&n,&m);
for(i=1;i<=m;i++){
int x,y,z;
scanf("%d %d %d",&x,&y,&z);
edge[x].push_back((node){y,z});
edge[y].push_back((node){x,z});
}
Dij(1,n,0);
int ans1=dis[0]
;
int ans2=0;
Dij(n,1,1);
for(i=1;i<=n;i++){
for(j=0;j<edge[i].size();j++){
int fr=i,to=edge[i][j].to,v=edge[i][j].v;
if(!(dis[0][fr]+dis[1][to]+v==ans1))continue;
node gai,hui;
gai.to=hui.to=to,gai.v=hui.v=v;
for(int k=0;k<edge[i].size();k++){
if(edge[i][k].to==gai.to&&edge[i][k].v==gai.v){
edge[i][k].v*=2;
memset(dis[3],0,sizeof(dis[3]));
Dij(1,n,3);
edge[i][k].v/=2;
ans2=max(ans2,dis[3]
);
break;
}
}
}
}printf("%d\n",ans2-ans1);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: