hdu 4725 The Shortest Path in Nya Graph

题意是把一幅图分成n层,在第x层的点可以去x+1层,x+1层的点也可以返回x层,花费为c。

再额外给m条边,问1到n的最短路。

建图的时候新建n个节点,每个节点表示第i层的顶点,顶点向第i层每个点连有向边,边权为0,同时原始点向其下一层和上一层的顶点连有向边,边权为c。表示这一层的点可以通过顶点花费为c进入相邻层的点,与题意相符。

再建输入的m条边。跑最短路即可。

#include <bits/stdc++.h>
#include <unordered_set>
#include <unordered_map>
#define pb push_back
#define mp make_pair
#define x first
#define y second
#define rep(i,x,y) for(i=x;i<=y;i++)
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define up rt,rt<<1,rt<<1|1
#define mem(x) memset(x,0,sizeof(x))
#define mem1(x) memset(x,-1,sizeof(x))
#define LMissher
using namespace std;
typedef long long ll;
typedef double db;
const int M = 2e5+7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const int mod = 1e9+7;

int _,n,m,i,c,cas=1;
int cnt,head[M],flag[M],val[M],vis[M];
struct edge{
    int w,v,nex;
}e[M<<3];
void init(){
    cnt=0;mem1(head);mem(vis);
}
void add(int u,int v,int w){
    e[++cnt].v=v;e[cnt].w=w;e[cnt].nex=head[u];
    head[u]=cnt;
}
struct node
{
    int dis,index;
    bool operator < (const node & k)const{
        return dis>k.dis;
    }
}d[M];
void dijkstra(int s){
    mem(flag);
    rep(i,0,n*2+1) d[i].dis=inf,d[i].index=i;
    d[s].dis=0;priority_queue<node> q;q.push(d[s]);
    while(!q.empty()){
        int u=q.top().index;q.pop();
        if(flag[u]) continue;
        flag[u]=1;
        for(int i=head[u];~i;i=e[i].nex){
            int v=e[i].v,w=e[i].w;
            if(d[v].dis>w+d[u].dis&&!flag[v]){
                d[v].dis=w+d[u].dis;
                q.push(d[v]);
            }
        }
    }
    if(d[n].dis==inf) d[n].dis=-1;
    printf("Case #%d: %d\n",cas++,d[n].dis);
}
int main(){
    #ifdef LMissher
        freopen("1.in","r",stdin);
        freopen("1.out","w",stdout);
    #endif
        scanf("%d",&_);
    while(_--){
        init();
        scanf("%d%d%d",&n,&m,&c);
        rep(i,1,n){
            scanf("%d",&val[i]);
            vis[val[i]]=1;
        }
        rep(i,1,n){
            add(val[i]+n,i,0);//一层中的顶点向点连边
            if(val[i]!=1&&vis[val[i]-1]){//向上一层连边
                add(i,val[i]+n-1,c);
            }
            if(val[i]!=n&&vis[val[i]+1]){//向下一层连边
                add(i,val[i]+n+1,c);
            }
        }
        rep(i,1,m){
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,w);add(v,u,w);
        }
        dijkstra(1);
    }
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/LMissher/p/9588994.html
今日推荐