POJ-3255-Roadblocks

来源:互联网 发布:电脑背包 知乎 编辑:程序博客网 时间:2024/06/05 04:14

这个题其实就是给你N个点,M条边,然后让你求出从点1到点N的次短路径。本来最开始想像次小生成树的方法去求,但看到数据量就知道不行。然后想了一下,如果要找次最短路径,那么它一定是在某一条边上走了绕路,所以我们可以求1号点到所有点的最短路径,以及n号点到所有点的最短路径,然后枚举边,求不等于最短路径的最小值即可。

我用的Spfa求的。

代码:

#include<cstdio>#include<cstring>#include<iostream>#include<queue>using namespace std;const int inf=1<<29;const int maxn=5100;const int maxm=(1e5+1000)*3;int n,m,e,head[maxn],nxt[maxm],cost[maxm],pnt[maxm],dist[2][maxn];bool vis[maxn];queue<int> q;struct Node{    int from;    int to;    int c;}E[maxm];void Init(){    e=0;    memset(head,-1,sizeof(head));}void AddEdge(int u,int v,int c){    pnt[e]=v;cost[e]=c;nxt[e]=head[u];head[u]=e++;    pnt[e]=u;cost[e]=c;nxt[e]=head[v];head[v]=e++;}void Spfa(int st,int index){    for(int i=0;i<=n;i++)dist[index][i]=inf;    memset(vis,0,sizeof(vis));    dist[index][st]=0;    q.push(st);    while(!q.empty())    {int u=q.front();q.pop();vis[u]=0;for(int i=head[u];i!=-1;i=nxt[i])    if(dist[index][pnt[i]]>dist[index][u]+cost[i])    {dist[index][pnt[i]]=dist[index][u]+cost[i];if(!vis[pnt[i]]){    q.push(pnt[i]);    vis[pnt[i]]=1;}    }    }}int main(){    while(scanf("%d%d",&n,&m)!=EOF)    {Init();for(int i=0;i<m;i++){    scanf("%d%d%d",&E[i].from,&E[i].to,&E[i].c);    AddEdge(E[i].from,E[i].to,E[i].c);}Spfa(1,0);Spfa(n,1);int mini=inf;for(int i=0;i<m;i++){    if(dist[0][E[i].from]+dist[1][E[i].to]+E[i].c<mini)if(dist[0][E[i].from]+dist[1][E[i].to]+E[i].c!=dist[0][n])    mini=dist[0][E[i].from]+dist[1][E[i].to]+E[i].c;    if(dist[1][E[i].from]+dist[0][E[i].to]+E[i].c<mini)if(dist[1][E[i].from]+dist[0][E[i].to]+E[i].c!=dist[0][n])    mini=dist[1][E[i].from]+dist[0][E[i].to]+E[i].c;}printf("%d\n",mini);    }    return 0;}


0 0
原创粉丝点击