您的位置:首页 > 其它

POJ 3255 Roadblocks

2016-03-14 09:55 162 查看
最短路预处理+枚举。

1到n的次短路长度必然等于 从1走到X的最短路+x到y的边权+y到n的最短路。

首先预处理好1到每一个节点的最短路,和n到每一个节点的最短路。

然后枚举每一条边作为中间边[x,y]或者[y,x],如果加起来长度是最短路则跳过,否则更新答案。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm>
using namespace std;

const int INF=0x7FFFFFFF;
const int maxn=5000+10;
struct Edge
{
int u,v;
int w;
}e[200000+10];
int n,m;
vector<int>g[maxn];
int dis[2][maxn];
bool flag[maxn];

void init()
{
for(int i=1;i<=n;i++) g[i].clear();
for(int i=1;i<=n;i++) dis[0][i]=dis[1][i]=INF;
dis[0][1]=0; dis[1]
=0;
}

void read()
{
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
g[e[i].u].push_back(i);
e[i+m].u=e[i].v; e[i+m].v=e[i].u; e[i+m].w=e[i].w;
g[e[i+m].u].push_back(i+m);
}
}

void SPFA(int st)
{
queue<int>Q; memset(flag,0,sizeof flag);
int now; if(st==1) now=0; else now=1;
Q.push(st); flag[st]=1;
while(!Q.empty())
{
int head=Q.front(); Q.pop(); flag[head]=0;
for(int i=0;i<g[head].size();i++)
{
int id=g[head][i];
int cost=e[id].w,to=e[id].v;
if(dis[now][head]+cost<dis[now][to])
{
dis[now][to]=dis[now][head]+cost;
if(!flag[to]) {flag[to]=1;Q.push(to);}
}
}
}
}

void work()
{
int f=dis[0]
;
int ans=INF;
for(int i=1;i<=2*m;i++)
{
int u=e[i].u, v=e[i].v;
if(dis[0][u]+e[i].w+dis[1][v]==f) continue;
ans=min(dis[0][u]+e[i].w+dis[1][v],ans);
}
printf("%d\n",ans);
}

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