HDU 4725 (加點)

鏈接: Vjudge

題意 : 給 n個點 m個雙向變 層之間的花費C 下一行給出每一個點所在層數 後面給U——>V的花費 求 1-n最小花費

看到第一眼就知道是dijk求,但是不會建圖(還讀錯題一次),練習賽的時候大佬都做出來了…. 自己還是太菜了

建圖方法 把每一層看成兩個點,多建 2*n個點,然後新建點到自己層點的距離爲0 到下一層新建的點爲 c 然後自己最短路跑就行了 (爲什麼不是每層多建一個點而是兩個呢? 這是因爲最短路的緣故 如果 1層的兩個點互不相連 這需要跑到上一層再跑回來 但再用dijk時無法回來(跟新點時那個點已經被標記))

代碼 :


#include <bits/stdc++.h>
using namespace std;
const long long mod=1e9+7;
#define ll long long
#define inf 0x3f3f3f3f
void intt()
{freopen("in","r",stdin);}

struct node
{
    int v;
    int cost;
    node(){}
    node(int x,int y):v(x),cost(y){}
    bool friend operator <(const node &a,const node &b)
    {
        return a.cost>b.cost;
    }
};
vector<node>qq[300007];

int n,m,c;
void dijk()
{
    int vis[300007];
    int dis[300007];
    memset(vis,0,sizeof(vis));
    memset(dis,inf,sizeof(dis));
    dis[1]=0;
    priority_queue<node>q;
    q.push(node(1,0));
    while(!q.empty())
    {

            node t=q.top();
            q.pop();
            if(vis[t.v]) continue;
            vis[t.v]=1;
            for(int i=0;i<qq[t.v].size();i++)
            {       int v=qq[t.v][i].v;
                  if(!vis[v]&&dis[v]>dis[t.v]+qq[t.v][i].cost)
                  {
                        dis[v]=dis[t.v]+qq[t.v][i].cost;
                        q.push(node(v,dis[v]));

                  }

            }




    }
    if(dis[n]==inf) printf("-1\n");
    else
   printf("%d\n",dis[n]);
}
int main()
{

   //intt();
    int t;
    int tt=1;
    scanf("%d",&t);
    while(t--)
    {
        for(int i=0;i<=3*n;i++) qq[i].clear();
        scanf("%d%d%d",&n,&m,&c);
        int maxx=0;
        for(int i=1;i<=n;i++)
        {
            int k;
            scanf("%d",&k);
            qq[n+k*2].push_back(node(i,0));
            qq[i].push_back(node(n+k*2-1,0));

        }
       for(int i=n+2;i<3*n;i+=2)
        {
            qq[i+1].push_back(node(i,c));
            qq[i-1].push_back(node(i+2,c));
        }


        for(int i=0;i<m;i++)
        {
            int u,v,val;
            scanf("%d%d%d",&u,&v,&val);
            qq[u].push_back(node(v,val));
            qq[v].push_back(node(u,val));

        }
        printf("Case #%d: ",tt++);
        dijk();

    }


    return 0;
}

努力!!加油!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章