Kattis dragonball1 Dragon Ball I(最短路)

There is a legendary tale about Dragon Balls on Planet X: if one collects seven Dragon Balls, the Dragon God will show up and help you fulfill your wishes.

One day, you are surprised to discover that the tale might possibly be true: you found a Dragon Ball radar at a flea market! The radar shows you the locations of the seven Dragon Balls on Planet X. You want to waste no time checking the truth of the old legend about wish-granting for yourself!

There are nn cities in total on the Planet X, numbered from 11 to nn. You are currently at city 11. To travel from one city to another, you can take any of mm bidirectional teleport trips, as many times as you like. The ii-th teleporter costs titi coins to use each time, and it can teleport you between cities aiai and bibi. To collect a Dragon Ball, you simply need to visit the city where it’s located, as indicated on your radar. It is possible that multiple Dragon Balls are at the same city; in this case you pick all of them all up at once if you visit that city.

Input

The first line of input contains two space-separated integers nn and m(1n,m200000)(1≤n,m≤200000), the number of cities and possible teleport trips. Then follow mm lines containing three space-separated integers aiai, bibi, and titi each (1ai,bin,0ti10000)(1≤ai,bi≤n,0≤ti≤10000), which, as explained above, represent the two cities connected by the teleport trip, and cost to use the teleporter. Then follows one line of seven space-separated integers, representing the city IDs of the seven Dragon Balls showing on the radar. Each ID cc satisfies the bound 1cn1≤c≤n.

Output

Print the minimum number of coins that you need to spend to collect all seven Dragon Balls shown on the Dragon Ball radar. If there is no way to complete this task, print 1−1 instead.

Sample Input 1Sample Output 1
10 9
1 2 1
2 3 1
3 4 1
4 5 1
5 6 1
6 7 1
7 8 1
8 9 1
9 10 1
1 2 3 4 5 6 7
6
Sample Input 2Sample Output 2
5 5
1 2 0
1 3 0
2 3 1
3 4 1
4 5 1
1 2 1 2 3 4 4
1

 

7个点,每个点当成起点跑一个最短路~~枚举排列方式计算一下

#include<bits/stdc++.h>
#include<iostream>
#include<cstring>
#include<string>
#define met(a,x) memset(a,x,sizeof(a));
#define rep(i,a,b) for(ll i = a;i <= b;i++)
#define bep(i,a,b) for(ll i = a;i >= b;i--)
#define lowbit(x) (x&(-x))
// #define mid ((l + r) >> 1)
// #define len (r - l + 1)
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define pb push_back
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a%b); }
ll lcm(ll a, ll b) { return a * b / gcd(a, b); }
typedef unsigned long long ull;
typedef pair<ll, ll>P;
typedef pair<ll, pair<ll, ll> > Pii;
const ll inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const double PI = acos(-1);
const ll maxn = 400100;
const ll mod = 1000000007;
int rd(){
    int flag=1;
    int sum=0;
    char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-')flag=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        sum=sum*10+c-'0';
        c=getchar();
    }
    return sum*flag;
}

struct node{
    ll v,w,net;
}e[maxn];
ll n,m,cnt,top,head[maxn],dis[10][maxn],vis[maxn];
ll a[10];
void add(ll u,ll v,ll w){
    e[cnt] = (node){v,w,head[u]};
    head[u] = cnt++;
}
void SPFA(ll now,ll s)
{
    rep(i,1,n)dis[now][i] = INF,vis[i] = 0;
    queue<int>que;
    que.push(s);
    dis[now][s]=0;
    while(!que.empty())
    {
        int u = que.front();
        que.pop();
        vis[u] = 0;
        for(int i=head[u]; i!=-1; i=e[i].net)
        {
            int v=e[i].v;
            int w=e[i].w;
            if(dis[now][v]>dis[now][u]+w)
            {
                dis[now][v]=dis[now][u]+w;
                if(!vis[v]){
                    vis[v] = 1;
                    que.push(v);
                }
            }
        }
    }
}
int main()
{
    n = rd(),m = rd();
    rep(i,1,n)head[i] = -1;
    rep(i,1,m){
        ll u = rd(),v = rd(),w = rd();
        add(u,v,w);add(v,u,w);
    }
    SPFA(0,1);
    rep(i,1,7){
        a[i] = rd();
        SPFA(i,a[i]);
    }
    ll path[10] = {0,1,2,3,4,5,6,7};
    ll ans = INF;
    do{
        ll di = 0;
        for(int i = 1;i <= 7;i++){
            di += dis[path[i-1]][a[path[i]]];
        }
        ans = min(ans,di);
    }while(next_permutation(path+1,path+1+7));
    cout << ans << endl;
    return 0;
}
View Code

 

posted @ 2020-02-03 15:05  cherish__lin  阅读(348)  评论(0编辑  收藏  举报