HDU 4725-J - The Shortest Path in Nya Graph-增点建图-层次网络-最短路

来源:互联网 发布:tuxera ntfs for mac 编辑:程序博客网 时间:2024/06/11 04:57

与hdu5521类似的层次网络最短路问题

http://acm.hdu.edu.cn/showproblem.php?pid=4725

题意是给 n个点,m个边,C

m条边u,v,w,w是边权

 除此之外给你一个个 layer[i],表示点i属于第 layer[i]层! 


关于层的性质有两个 【如果相邻两层都存在节点,则x层任意节点可以与x+1层任意节点互通,代价为C】

当然如果有一层为空,则空层是无法与上下层相通的哦!相当于断层!


建图方法和hdu5521一致,增一个点代表一层,不同的是,5521是【每一层的所有点互通】,而本题只要求相邻层互通,

注意:【层之内是不允许互通的】

因此建图需要注意 不能直接 【把新new的点 与层内的所有点直接建立双向边

应该 

A   【建立 该层内的节点 指向 当前层的新new的虚拟节点的单向边】【权值为0】

B、【第i层的虚拟节点指向 i+1层的所有node】【权值为C】

C、【第i+1层的虚拟节点指向 i层的所有node】【权值为C】

【这样就能确保符合题意,两层内任意节点互通,但同层节点不连通


dji:561ms

#include <iostream>#include<cstdio>#include<algorithm>#include<cstdlib>#include<cstring>#include<vector>#include<queue>using namespace std;struct node{    int x;    int v;    node() {}    node(int a,int b)    {        x=a,v=b;    }    bool operator <(const node&b) const    {        return v>b.v;    }};vector<node >mp[200005];vector <int >layer[200005];int idx;int vis[200005];priority_queue<node> q;int dis[200005];const int inf=1e9;int main(){    int cnt=1;    void dji();    int t;    cin>>t;    while(t--)    {        int n,m,c;        int i,j;        cin>>n>>m>>c;        int x,y,v;        for (i=1; i<=n*2; i++) mp[i].clear();        for (i=1;i<=n*2;i++)        layer[i].clear();        for (i=1; i<=n; i++)        {            scanf("%d",&x);            layer[x].push_back(i);        }        for (i=1; i<=m; i++)        {            scanf("%d%d%d",&x,&y,&v);            mp[x].push_back(node(y,v));            mp[y].push_back(node(x,v));        }        idx=n;        for (i=1; i<=n; i++)        {            idx++;            if (layer[i].size()==0) continue;            for (j=0; j<layer[i].size(); j++)            {                  v=layer[i][j];            //mp[idx].push_back(node(v,0));原先的错误建图法                mp[v].push_back(node(idx,0));            }        }        for (i=n+1; i<idx; i++)        {            if (layer[i-n].size()==0||layer[i-n+1].size()==0) continue;            mp[i].push_back(node(i+1,c));             for (j=0; j<layer[i-n].size(); j++)//更正后的建图法            {                  v=layer[i-n][j];                mp[i+1].push_back(node(v,c));   //i+1-n层的虚拟节点指向i-n层的node            }             for (j=0; j<layer[i-n+1].size(); j++)//更正后的建图法            {                  v=layer[i-n+1][j];                mp[i].push_back(node(v,c));//i-n层的虚拟节点指向下一层的node            }        }        dji();        printf("Case #%d: ",cnt++);        if (dis[n]==inf) printf("-1\n");        else        printf("%d\n",dis[n]);    }    return 0;}void dji(){    while(!q.empty())q.pop();    int i;    for (i=1;i<=idx;i++)    {        dis[i]=inf;        vis[i]=0;    }    dis[1]=0;    node st(1,0);    q.push(st);    while(!q.empty())    {        node t=q.top();        q.pop();        int num=t.x;        if (vis[num])continue;        vis[num]=1;        for (i=0;i<mp[num].size();i++)        {            node tmp=mp[num][i];            int x=tmp.x;            int v=tmp.v;            if (!vis[x]&&v+dis[num]<dis[x])            {                dis[x]=v+dis[num];                q.push(node(x,dis[x]));            }        }    }}


0 0
原创粉丝点击