ACM-ICPC 2018 南京賽區網絡預賽 L. Magical Girl Haze (拆點+最短路)

https://nanti.jisuanke.com/t/31001

題意:

有n個城市,m條有向路,最多選取k條路的權值爲0,求1到n的最短路。

 

思路:

我們可以當每個點分成k 層,同一層的點的權值爲w,到下一層的權值爲0,這樣建圖,就能保證最短k條邊的權值爲0,然後跑最短路。

 

代碼:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=2e6+10;
const int maxm=5e6+10;
const ll inf=1e18;
struct node
{
    int u,v,w,next;
}edge[maxm];
int head[maxn];
int n,m,k;
int cnt;
struct Node
{
    int id;
    ll cost;
}dis[maxn];
bool operator<(Node a,Node b)
{
    return a.cost>b.cost;
}

void init()
{
    cnt=0;
    memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int w)
{
    for(int i=0;i<=k;i++)
    {
        edge[cnt].u=u+i*n;
        edge[cnt].v=v+i*n;
        edge[cnt].w=w;
        edge[cnt].next=head[u+i*n];
        head[u+i*n]=cnt++;
    }
    for(int i=0;i<k;i++)
    {
        edge[cnt].u=u+i*n;
        edge[cnt].v=v+(i+1)*n;
        edge[cnt].w=0;
        edge[cnt].next=head[u+i*n];
        head[u+i*n]=cnt++;
    }
}
bool vis[maxn];
void dij()
{
    for(int i=1;i<=n*k+n;i++)
        dis[i].id=i,dis[i].cost=inf;
    dis[1].cost=0;
    priority_queue<Node>q;
    q.push(dis[1]);
    while(!q.empty())
    {
        Node u=q.top();
        q.pop();
        for(int i=head[u.id];i!=-1;i=edge[i].next)
        {
            int v=edge[i].v;
            int w=edge[i].w;
            if(dis[v].cost>dis[u.id].cost+w)
                dis[v].cost=dis[u.id].cost+w,q.push(dis[v]);
        }
    }

}
int main()
{
    int T;
    scanf("%d",&T);
     while(T--)
     {
         scanf("%d%d%d",&n,&m,&k);
         init();
         int u,v,w;
         for(int i=0;i<m;i++)
         {
             scanf("%d%d%d",&u,&v,&w);
             addedge(u,v,w);
         }
         dij();
         printf("%lld\n",dis[n*k+n].cost);
     }
    return 0;
}

 

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