鏈接: 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;
}
努力!!加油!