Live2d Test Env

Gym:101630J - Journey from Petersburg to Moscow(最短路)

题意:求1到N的最短路,最短路的定义为路径上最大的K条边。

思路:对于每种边权,假设为X,它是第K大,那么小于X的变为0,大于K的,边权-X。然后求最短路,用dis[N]+K*X更新答案。

而小于K的情况下,最短路显然就是原图的最短路。(还是不好想的

#include<bits/stdc++.h>
#define ll long long
#define mp make_pair
#define pii pair<ll,int>
#define F first
#define S second
const int maxn=3010;
const ll inf=1LL<<60;
using namespace std;
vector<pii>G[maxn]; int vis[maxn],N; ll a[maxn],ans,dis[maxn];
void dijs(ll x)
{
    priority_queue<pii,vector<pii>,greater<pii> >q;
    int vis[maxn];
    for(int i=1;i<=N;i++) dis[i]=inf,vis[i]=0;
    q.push(mp(0,1)); dis[1]=0;
    while(!q.empty()){
        pii t=q.top(); q.pop();
        int u=t.S, L=G[u].size();     
        for(int i=0;i<L;i++){
            int v=G[u][i].S; ll c=G[u][i].F-x;
            if(c<0) c=0;
            if(dis[v]>dis[u]+c){
                dis[v]=dis[u]+c;
                if(!vis[v]) vis[v]=1,q.push(mp(dis[v],v));
            }
        }
        vis[u]=0;
    }
}
int main()
{
    int M,K,u,v,i; ll c;
    scanf("%d%d%d",&N,&M,&K);
    for(i=1;i<=M;i++){
        scanf("%d%d%I64d",&u,&v,&c);
        G[u].push_back(mp(c,v));
        G[v].push_back(mp(c,u));
        a[i]=c;
    }
    dijs(0);  ans=dis[N];
    for(i=1;i<=M;i++) {
        dijs(a[i]);
        ll tmp=dis[N]+(ll)K*a[i];
        ans=min(tmp,ans);
    }
    printf("%I64d\n",ans);
    return 0;
}

 

posted @ 2018-07-16 22:05  nimphy  阅读(519)  评论(0编辑  收藏  举报