poj3255次短路

来源:互联网 发布:ubuntu下安装jdk9 编辑:程序博客网 时间:2024/04/26 23:37


题意:求出1 -> n的次短路;

思路:

1.可以跑两遍最短路,从1 -> n 和 n -> 1,因为次短路肯定是替换最短路上的一条边后形成的,所以之后直接枚举每条边替换就行了。


2.在dijkstra的时候同时更新最短和次短,比较巧妙。


PS:两种思路在有向图中同样适用,不过思路一在跑n - > 1的时候要建反向图。



Code1:

#include<iostream>#include<cstdio>#include<queue>#include<cstring>using namespace std;typedef long long ll;const int maxn = 5000 + 10;#define INF 0x3f3f3f3f#define clr(x,y) memset(x,y,sizeof x)int n,m;int edge_num;int head[maxn];int d1[maxn],d2[maxn];struct Edge{    Edge(){}    Edge(int x,int y,int z):to(x),w(y),next(z){}    int to,w,next;}edge[200000 + 10];void Init(){    clr(head,-1);    edge_num = 0;    clr(d1,INF);clr(d2,INF);}void add_edge(int x,int y,int z){    edge[edge_num] = Edge(y,z,head[x]);    head[x] = edge_num ++;}bool vis[maxn];void spfa(int s,int d[]){    clr(vis,false);    d[s] = 0;    queue<int>q;    q.push(s);    vis[s] = true;    while(!q.empty())    {        int u = q.front();q.pop();        vis[u] = false;        for(int i = head[u];i != -1; i = edge[i].next)        {            int v = edge[i].to,w = edge[i].w;            if(d[v] > d[u] + w)            {                d[v] = d[u] + w;                if(!vis[v])                    vis[v] = true,q.push(v);            }        }    }}void solve(){    int ans = INF;    for(int i = 1; i <= n; i ++)    {        for(int j = head[i];j != -1; j = edge[j].next)        {            int v = edge[j].to,w = edge[j].w;            if(d1[i] + d2[v] + w > d1[n])                ans = min(ans,d1[i] + d2[v] + w);        }    }    printf("%d\n",ans);}int main(){    while( ~ scanf("%d%d",&n,&m))    {        Init();        while(m --)        {            int x,y,z;            scanf("%d%d%d",&x,&y,&z);            add_edge(x,y,z);            add_edge(y,x,z);        }        spfa(1,d1);        spfa(n,d2);        solve();    }    return 0;}

Code2:

#include<iostream>#include<cstdio>#include<queue>#include<cstring>using namespace std;typedef long long ll;const int maxn = 5e3 + 10;#define INF 0x3f3f3f3f#define clr(x,y) memset(x,y,sizeof x)typedef pair<int,int> P;struct Node{    Node(int x,int y):to(x),val(y){}    int to;    int val;};int n,m;vector<Node>v[maxn];int dist[maxn],dist2[maxn];void dijkstra(){    clr(dist,INF);    clr(dist2,INF);    priority_queue<P,vector<P>,greater<P> >q;    dist[1] = 0;    q.push(P(0,1));    while(!q.empty())    {        P t = q.top();q.pop();        int u = t.second;        if(dist2[u] < t.first)            continue;        for(int i = 0; i < v[u].size(); i ++)        {            int vs = v[u][i].to,cost = v[u][i].val;            int d = t.first + cost;            if(d < dist[vs])            {                swap(dist[vs],d);                q.push(P(dist[vs],vs));            }            if(dist[vs] < d && dist2[vs] > d)            {                dist2[vs] = d;                q.push(P(dist2[vs],vs));            }        }    }    printf("%d\n",dist2[n]);}int main(){    while( ~ scanf("%d%d",&n,&m))    {        for(int i = 1; i <= n; i ++)            v[i].clear();        while(m --)        {            int x,y,z;            scanf("%d%d%d",&x,&y,&z);            v[x].push_back(Node(y,z));            v[y].push_back(Node(x,z));        }        dijkstra();    }    return 0;}