zoukankan      html  css  js  c++  java
  • 2020 MULTI-UNIVERSITY TRAINING CONTEST 3 Tokitsukaze and Rescue (最短路+dfs)

    题面

    Princess CJB has lived almost her entire life in the isolated town of Ertona, where CJB uses her unique ability to recognize where crystals of materials are buried. By way of a fateful encounter, CJB learns of the Alchemy Exam and decides to take her first step into the outside world, setting off on a grand journey to become a certified alchemist and discover the mysteries that life has to offer!

    In order to take part in the Alchemy Exam, CJB goes to the Reisenberg town without any partners. But the kingdom Adalet is unbelievably enormous so that there are many hidden risks. Claris, a powerful evil magician, wants to monopolize CJB for the extraordinary beauty of her. Due to the power limitation of CJB, she can't escape from Claris without any assistance. The alchemist Tokitsukaze has heard this savage act and wants to rescue the princess CJB.

    There are n cities numbered from 1 to n in the kingdom Adalet. Because of the excellent transportation, there is exactly a two-way road between any two cites. Tokitsukaze lives in city 1. The Magician Claris lives in city n. Since the exam will be held soon, Tokitsukaze wants to rescue CJB as fast as possible, so she will choose the shortest path to reach city n.

    Claris has also heard this news and is afraid of being punished, so he decides to slow Tokitsukaze down by making an explosion on k roads he chose and causing these roads to lose their capability of two-way transportation, since it can pave the way for having enough time to prepare his powerful magic against Tokitsukaze.

    Tokitsukaze knows some roads will be destroyed and can immediately recognize where they are, but she has no approach to prevent this explosion, so she chooses just to move along the shortest path after Claris completes his explosion.

    Now Claris wants to know, after finishing his explosion, what the longest possible length is of the shortest path from city 1 to city n.

    Input
    There are several test cases.

    The first line contains an integer T (1≤T≤100), denoting the number of test cases. Then follow all the test cases.

    For each test case, the first line contains two integers n and k (3≤n≤50,1≤k≤min(n−2,5)), denoting the number of cities and the number of roads being exploded, respectively.

    The next n(n−1)2 lines describe all the roads, where each line contains three integers u, v and w (1≤u,v≤n,u≠v,1≤w≤104), representing a two-way road of length w between city u and city v. It is guaranteed that for every two cities, there exists exactly one road whose length is randomly distributed between 1 and 104.

    Output
    For each case, output in one line an integer, denoting the longest possible length of the shortest path after the explosion.

    Sample Input
    3
    5 1
    1 2 2990
    1 3 2414
    1 4 4018
    1 5 6216
    2 3 9140
    2 4 4169
    2 5 550
    3 4 6618
    3 5 3206
    4 5 105
    5 2
    1 2 2990
    1 3 2414
    1 4 4018
    1 5 6216
    2 3 9140
    2 4 4169
    2 5 550
    3 4 6618
    3 5 3206
    4 5 105
    5 3
    1 2 2990
    1 3 2414
    1 4 4018
    1 5 6216
    2 3 9140
    2 4 4169
    2 5 550
    3 4 6618
    3 5 3206
    4 5 105

    Sample Output
    4123
    5620
    6216

    思路

    当然先开始蒙了一发k短路,好吧,虽然样例一样,完全不是这个东西。是这样的,由于数据随机并且点数不会太多,我们考虑一下暴力删边,然后dfs递归去删下一条边,复杂度n2*c的k次 (递归删边)。

    代码实现

    #include<cstdio>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<map>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    using namespace std;
    #define rep(i,f_start,f_end) for (int i=f_start;i<=f_end;++i)
    #define per(i,n,a) for (int i=n;i>=a;i--)
    #define MT(x,i) memset(x,i,sizeof(x) )
    #define rev(i,start,end) for (int i=0;i<end;i++)
    #define inf 0x3f3f3f3f
    #define mp(x,y) make_pair(x,y)
    #define lowbit(x) (x&-x)
    #define MOD 1000000007
    #define exp 1e-8
    #define N 1000005 
    #define fi first 
    #define se second
    #define pb push_back
    typedef long long ll;
    typedef pair<int ,int> PII;
    typedef pair<int ,PII> PIII;
    ll gcd (ll a,ll b) {return b?gcd (b,a%b):a; }
    inline int read() {
        char ch=getchar(); int x=0, f=1;
        while(ch<'0'||ch>'9') {
            if(ch=='-') f = -1;
            ch=getchar();
        } 
        while('0'<=ch&&ch<='9') {
            x=x*10+ch-'0';
            ch=getchar();
        }   return x*f;
    }
    int t,n,k;
    const int maxn=1003;
    ll ans;
    int vis[maxn];
    int path[maxn];
    ll dis[maxn];
    int maze[maxn][maxn];
    
    void dijkstra (int s) {
       priority_queue <PII,vector <PII>,greater<PII> > q;
       rep (i,1,n) {
           dis[i]=inf;
           vis[i]=0;
           path[i]=-1;
       }
       dis[s]=0;
       q.push (mp (dis[s],s));
       while (q.size ()) {
           PII temp=q.top ();
           q.pop ();
           int x=temp.second;
           if (vis[x]) continue;
           vis[x]=1;
           rep (i,1,n) {
               int v=i;
               int w=maze[x][i];
               if (!maze[x][i]) continue;
               if (dis[v]>dis[x]+1ll*w) {
                   dis[v]=dis[x]+w;
                   path[v]=x;
                   q.push (mp(dis[v],v));
               }
           }
       }
    }
    
    void dfs (int cnt) {
        dijkstra (1);
        if (cnt==k) {
            ans=max (ans,dis[n]);
            return ;
        }
        vector <int > va;
        int now=n;
        va.pb (now);
        while (now!=1) {
            now=path[now];
            va.pb (now);
        } 
        int sz=va.size ();
        rep (i,0,sz-2) {
            int u=va[i],v=va[i+1];
            int temp=maze[u][v];
            maze[u][v]=inf,maze[v][u]=inf;
            dfs (cnt+1);
            maze[u][v]=temp,maze[v][u]=temp;
        }
    
    }
    
    void solve () {
       ans=0;
       n=read (); k=read ();
       rep (i,0,n) 
        rep (j,0,n) maze[i][j]=inf;
       rep (i,1,n*(n-1)/2) {
           int u=read (),v=read (),w=read ();
           maze[u][v]=maze[v][u]=w;
       }
       dfs (0);
       cout<<ans<<endl;
    }
    
    int main () {
        cin>>t;
        while (t--) {
            solve ();
        }
        return 0;
    }
    
  • 相关阅读:
    纯JavaScripst的全选、全不选、反选 【转】
    Java 文件和byte数组转换
    nc命令使用详解
    mtr 命令详解
    Nginx主动检测方案---Tengine
    Apache相关安全设置
    tomcat APR的配置
    Vsftpd 配置详解
    FTP主动模式和被动模式的区别
    iptables配置详解
  • 原文地址:https://www.cnblogs.com/hhlya/p/13406163.html
Copyright © 2011-2022 走看看