zoukankan      html  css  js  c++  java
  • HDU6797 多校第三场 Tokitsukaze and Rescue

    题意:

    给一个N个点的完全图 有边权

    然后你可以删K条边,让剩下的图的最短路最长

    题解:

    发现K很小,暴力搜一下,

    再想一下,只搜当前最短路上的边就可以

    复杂度未知,本地跑的挺快,然后交就完事了(引自zbr)

    #include<bits/stdc++.h>
    #define rep(i,a,n) for(int i=a;i<=n;++i)
    #define per(i,a,n) for(int i=n;i>=a;--i)
    #define pb push_back
    #define fi first
    #define se second
    #define io std::ios::sync_with_stdio(false)
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pii;
    const int P = 1e9+7, INF = 0x3f3f3f3f;
    ll gcd(ll a,ll b)
    {
        return b?gcd(b,a%b):a;
    }
    ll qpow(ll a,ll n)
    {
        ll r=1%P;
        for (a%=P; n; a=a*a%P,n>>=1)if(n&1)r=r*a%P;
        return r;
    }
    const int maxn=51;
    int n;
    int k;
    vector<int> G[maxn];
    int d[maxn];
    int fa[maxn];
    int dis[maxn][maxn];
    void djs(int s)
    {
        priority_queue<pii,vector<pii>,greater<pii> > que;
        memset(d,INF,sizeof(d));
        d[s]=0;
        que.push(make_pair(0,s));
        while(!que.empty())
        {
            pii p=que.top();
            que.pop();
            int v=p.second;
            if(d[v]<p.first)continue;
            for(int i=0; i<G[v].size(); i++)
            {
                int to=G[v][i];
                if(d[to]>d[v]+dis[to][v])
                {
                    d[to]=d[v]+dis[to][v];
                    fa[to]=v;
                    que.push(make_pair(d[to],to));
                }
            }
        }
    }
    int ans=0;
    void dfs(int i)
    {
        djs(1);
        if(i==k+1)
        {
            ans=max(ans,d[n]);
                return ;
        }
        int x,y;
        int cur=n;
        while(1)
        {
            x=cur;
            y=fa[cur];
            int temp=dis[x][y];
            dis[x][y]=INF;
            dis[y][x]=INF;
            dfs(i+1);
            dis[x][y]=temp;
            dis[y][x]=temp;
            djs(1);
            cur=fa[cur];
            if(cur==1)
                break;
    
        }
    }
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {   ans=0;
            cin>>n>>k;
            for(int i=1; i<=n; i++)
                G[i].clear();
            for(int i=1; i<=(n-1)*n/2; i++)
            {
                int x,y,w;
                cin>>x>>y>>w;
                G[x].push_back(y);
                G[y].push_back(x);
                dis[x][y]=w;
                dis[y][x]=w;
            }
            dfs(1);
            cout<<ans<<endl;
        }
    }

    这个代码比赛时候过了,然后看评论说TLE,然后我又交了一发确实T了 ,难道是赛后加强了数据?

    看了看代码发现还能改进一下。

    这份代码不会T,每次记录一次father就行了,就不用每次跑一次最短路了

    #include<bits/stdc++.h>
    #define rep(i,a,n) for(int i=a;i<=n;++i)
    #define per(i,a,n) for(int i=n;i>=a;--i)
    #define pb push_back
    #define fi first
    #define se second
    #define io std::ios::sync_with_stdio(false)
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pii;
    const int P = 1e9+7, INF = 0x3f3f3f3f;
    ll gcd(ll a,ll b)
    {
        return b?gcd(b,a%b):a;
    }
    ll qpow(ll a,ll n)
    {
        ll r=1%P;
        for (a%=P; n; a=a*a%P,n>>=1)if(n&1)r=r*a%P;
        return r;
    }
    const int maxn=51;
    int n;
    int k;
    vector<int> G[maxn];
    int d[maxn];
    int fa[maxn];
    int dis[maxn][maxn];
    void djs(int s)
    {
        priority_queue<pii,vector<pii>,greater<pii> > que;
        memset(d,INF,sizeof(d));
        d[s]=0;
        que.push(make_pair(0,s));
        while(!que.empty())
        {
            pii p=que.top();
            que.pop();
            int v=p.second;
            if(d[v]<p.first)continue;
            for(int i=0; i<G[v].size(); i++)
            {
                int to=G[v][i];
                if(d[to]>d[v]+dis[to][v])
                {
                    d[to]=d[v]+dis[to][v];
                    fa[to]=v;
                    que.push(make_pair(d[to],to));
                }
            }
        }
    }
    int ans=0;
    void dfs(int i)
    {
        djs(1);
        if(i==k+1)
        {
            ans=max(ans,d[n]);
                return ;
        }
        int x,y;
        int cur=n;
        int faa[maxn];
        for(int i=1;i<=n;i++)
        {
            faa[i]=fa[i];
        }
        while(1)
        {
            x=cur;
            y=faa[cur];
            int temp=dis[x][y];
            dis[x][y]=INF;
            dis[y][x]=INF;
            dfs(i+1);
            dis[x][y]=temp;
            dis[y][x]=temp;
            //djs(1);
            cur=faa[cur];
            if(cur==1)
                break;
    
        }
    }
    
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {   ans=0;
            cin>>n>>k;
            for(int i=1; i<=n; i++)
                G[i].clear();
            for(int i=1; i<=(n-1)*n/2; i++)
            {
                int x,y,w;
                cin>>x>>y>>w;
                G[x].push_back(y);
                G[y].push_back(x);
                dis[x][y]=w;
                dis[y][x]=w;
            }
            dfs(1);
            cout<<ans<<endl;
        }
    }
  • 相关阅读:
    POJ 3970(最小公倍数LCM)
    06005_Jedis入门
    雷林鹏分享:C# 字符串(String)
    雷林鹏分享:C# 类(Class)
    雷林鹏分享:C# 枚举(Enum)
    雷林鹏分享:C# 运算符重载
    雷林鹏分享:C# 多态性
    雷林鹏分享:C# 命名空间(Namespace)
    雷林鹏分享:C# 接口(Interface)
    雷林鹏分享:C# 正则表达式
  • 原文地址:https://www.cnblogs.com/acmLLF/p/13392329.html
Copyright © 2011-2022 走看看