您的位置:首页 > 其它

HDU 4725 The Shortest Path in Nya Graph

2015-09-10 22:40 435 查看
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4725

这道题的题意就是给你n层,每一层有几个点,然后每个点可以转移到相邻层的点上去,要花费C的时间,在另外给你一些边,这些边可以相互转移,花费一定的时间,要求1好点到n号点的最短距离。

题意不难理解,但是建图比较麻烦,虽然是一个很明显的分层图,但是由于有着层这个东西的限制,所以要考虑这个因素才行。有两种建图的方式。第一种: 每一层建两个点,一个出点一个入点,,然后层内的点和这两个点相连,距离为0,层与层之间,出点连另一个的入点,距离为响应距离,这样先把框架建好,再建额外的边,然后跑最短路。

第二种:每一层对应一个点,吧层内的点与这个点相连,费用为0,,然后每一个点连相邻的层的点,费用为C,剩下的不变。

第一种方法边和点比较多,但是不用一出错,第二种方法的话边和点相对较少,但是容易错在边和点相连的时候是单向边(想一想,为什么)。图能够建好,直接跑最短路就行了。另外有一点需要注意的是,只有相邻的层都有点,才能练边,因为并不是从某一层转移到某一层,而是从点转移到点,既然要到某一层,一定是到了某一个点。

AC代码

[code]//
//  Created by  CQU_CST_WuErli
//  Copyright (c) 2015 CQU_CST_WuErli. All rights reserved.
//
// #include<bits/stdc++.h>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <map>
#include <queue>
#include <stack>
#include <set>
#include <algorithm>
#include <sstream>
#define CLR(x) memset(x,0,sizeof(x))
#define OFF(x) memset(x,-1,sizeof(x))
#define MEM(x,a) memset((x),(a),sizeof(x))
#define ALL(x) x.begin(),x.end()
#define AT(i,v) for (auto &i:v)
#define For_UVa if (kase!=1) cout << endl
#define BUG cout << "I am here" << endl
#define lookln(x) cout << #x << "=" << x << endl
#define look(x) cout << #x << "=" << x
#define SI(a) scanf("%d",&a)
#define SII(a,b) scanf("%d%d",&a,&b)
#define SIII(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define root 1,n,1
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define BigInteger bign
const int MAX_L=2005;// For BigInteger
const int INF_INT=0x3f3f3f3f;
const long long INF_LL=0x7fffffff;
const int MOD=1e9+7;
const double eps=1e-9;
const double pi=acos(-1);
typedef long long  ll;
using namespace std;

const int N=(1e5+10)*20;
int pnt
,nxt
,head[100010*2],cost
;
int cnt=0;

void add_edge(int u,int v,int c){
    pnt[cnt]=v;nxt[cnt]=head[u];head[u]=cnt;
    cost[cnt++]=c;
}
int n,m,c;
int lay[100010*2];
int vis[100010*2],d[100010*2];

int spfa(){
    CLR(vis);MEM(d,INF_INT);
    queue<int> q;
    q.push(1);
    vis[1]=1;
    d[1]=0;
    while (!q.empty()){
        int x=q.front();q.pop();
        vis[x]=0;
        for (int i=head[x];~i;i=nxt[i]){
            int v=pnt[i];
//          if (v==x) continue;
            if (d[v]>d[x]+cost[i]){
                d[v]=d[x]+cost[i];
                if (!vis[v]){
                    vis[v]=1;
                    q.push(v);
                }
            }
        }
    }
    return d
;
}

int is
;

int main(){
#ifdef LOCAL
    freopen("C:\\Users\\john\\Desktop\\in.txt","r",stdin);
//  freopen("C:\\Users\\john\\Desktop\\out.txt","w",stdout);
#endif
    // 1->n nodes  n+1->n+n layer 
    int _;
    for (int kase=scanf("%d",&_);kase<=_;kase++){
        CLR(is);cnt=0;OFF(head);
        SIII(n,m,c);
        for (int i=1;i<=n;i++){
            int x;SI(x);x+=n;
            lay[i]=x;
            is[x]=1;
        }
        for (int i=n+1;i<n+n;i++){
            if (is[i] && is[i+1]) {
                add_edge(i,i+1,c);
                add_edge(i+1,i,c);
            }
        }
        for (int i=1;i<=n;i++){
            add_edge(lay[i],i,0);
            if (lay[i]>n+1) add_edge(i,lay[i]-1,c);
            if (lay[i]<n+n) add_edge(i,lay[i]+1,c);
        }
        for (int i=1;i<=m;i++){
            int u,w,v;
            SIII(u,v,w);
            add_edge(u,v,w);
            add_edge(v,u,w); 
        }
        printf("Case #%d: ",kase);
        int ans=spfa();
        if (ans>=INF_INT) cout << "-1\n";
        else cout << ans << endl;
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: