hdu 6181 Two Paths (多校第十场)

来源:互联网 发布:photoshop cc mac版本 编辑:程序博客网 时间:2024/04/30 10:15

题目链接:点击打开链接

求一个图上的次短路,每条边可以重复使用。Dijstra变形,vis[]数组记录访问结点的次数,当第二次访问所求结点的时候,qnode中保存的权值就是答案。

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <queue>using namespace std;typedef long long llt;const int MAXN=100010;const llt INF=0x3f3f3f3f3f3f3f3f;struct edge_t{    int v,next,weight;}edge[MAXN<<1];struct qnode{    int v;    llt c;    qnode(int _v=0,llt _c=0) {v=_v;c=_c;}    bool operator < (const qnode &r)const {return c>r.c;}};int Ecnt;int vertex[MAXN];void init_Graph(){    Ecnt=1;    memset(vertex,0,sizeof(vertex));}inline void Build_edge(int a,int b,int weight){    edge[Ecnt].v=b;    edge[Ecnt].weight=weight;    edge[Ecnt].next=vertex[a];    vertex[a]=Ecnt++;}//vis[]数组表示该节点访问次数int vis[MAXN];void Dijstra(int n,int s){    llt ans=INF;    memset(vis,0,sizeof(vis));    priority_queue<qnode> que;    while(!que.empty()) que.pop();    que.push(qnode(s,0));    while(!que.empty())    {        qnode tmp=que.top();        que.pop();        int u=tmp.v;        //此时求得不同于最短路的次短路,返回答案        if(u==n&&vis[u]==1)        {            ans=tmp.c;            break;        }        if(vis[u]==2) continue;        vis[u]++;        for(int i=vertex[u];i;i=edge[i].next)        {            int v=edge[i].v;            int cost=edge[i].weight;            //虽然结点可以重复使用,但是所求的次短路每个结点最多经过两次            if(vis[v]<2) que.push(qnode(v,tmp.c+cost));        }    }    printf("%lld\n",ans);}int main(){    int T;    int N,M;    int a,b,c;    scanf("%d",&T);    while(T--)    {        init_Graph();        scanf("%d%d",&N,&M);        for(int i=1;i<=M;i++)        {            scanf("%d%d%d",&a,&b,&c);            Build_edge(a,b,c);            Build_edge(b,a,c);        }        Dijstra(N,1);    }    return 0;}