lightoj 1099【dijkstra/BFS】

来源:互联网 发布:java应用程序开发实例 编辑:程序博客网 时间:2024/06/05 01:57

题意:

求 1-N 的第二长路,一条路可以重复走
if two or more shortest paths exist, the second-shortest path is the one whose length is longer than those but no longer than any other path
思路:
一开始想的就是:
我只要在spfa中更新的时候记录 dis[1][i]的最小和次小就好啦;
其实每个权值都带一个附属权值就好了;
这样能解决的好少,光是重复就不行了;
正确思路:

思想类似dijkstra 算法里:每次取最小边然后更新一波,只不过这里最小边有两种罢了;

次短路要么从某个最短路过来,要么从某个次短路过来。对于从1过去的点,只要有被更新到最短路或者次短路,那么就要对所有的点都搞一遍,每次取最小的边,然后一直更新;
引我南哥的小代码:
#include <cstdio>#include <cstring>#include <cstdlib>#include <string>#include <iostream>#include <algorithm>#include <sstream>#include <cmath>using namespace std;#include <queue>#include <stack>#include <set>#include <vector>#include <deque>#include <map>#define cler(arr, val)    memset(arr, val, sizeof(arr))#pragma comment(linker, "/STACK:102400000,102400000")typedef long long  LL;const int MAXN = 5010+1;const int MAXM = 240000;const int INF = 0x3f3f3f3f;const int mod = 1000000007;int d[MAXN][2],head[MAXN],tol;bool vis[MAXN][2];struct node{    int u,v,val,next;}edge[MAXM];void addedge(int u,int v,int w){    edge[tol].u=u,edge[tol].v=v,edge[tol].val=w,edge[tol].next=head[u];    head[u]=tol++;    edge[tol].u=v,edge[tol].v=u,edge[tol].val=w,edge[tol].next=head[v];    head[v]=tol++;}void dij(int n){    for(int i=0;i<=n;i++)        d[i][0]=d[i][1]=INF,vis[i][0]=vis[i][1]=false;    d[0][0]=0;    while(true)    {        int v=-1,k;        int minlen=INF;        for(int u=0;u<n;u++)        {            for(int l=0;l<2;l++)                if(!vis[u][l]&&(v==-1||d[u][l]<minlen))                {                    minlen=d[u][l];                    k=l;                    v=u;                }        }        if(v==-1) break;        vis[v][k]=true;        for(int i=head[v];~i;i=edge[i].next)        {            int u=edge[i].v;//目标            int cost=d[v][k]+edge[i].val;            if(cost<d[u][0])            {                d[u][1]=d[u][0];                d[u][0]=cost;            }            else if(cost<d[u][1]&&cost>d[u][0])            {                d[u][1]=cost;            }        }    }}int main(){#ifndef ONLINE_JUDGE       freopen("in.txt", "r", stdin);   //  freopen("out.txt", "w", stdout);#endif    int t,n,m,u,v,w,cas=1;    cin>>t;    while(t--)    {        cler(head,-1);        tol=0;        cin>>n>>m;        int a=0;        for(int i=0;i<m;i++)        {            scanf("%d%d%d",&u,&v,&w);            a=max(a,u);            a=max(a,v);            u--,v--;            addedge(u,v,w);        }        dij(a);        printf("Case %d: %d\n",cas++,d[n-1][1]);    }    return 0;}




0 0
原创粉丝点击