• poj 2288 tsp经典问题


    题目链接:http://poj.org/problem?id=2288

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    const int maxn = 13;
    typedef long long int ll_int;
    
    ll_int dp[maxn][maxn][1<<maxn];
    ll_int way[maxn][maxn][1<<maxn];
    int G[maxn][maxn];
    int V[maxn];
    
    int main()
    {
       freopen("E:\acm\input.txt","r",stdin);
        int T;
        cin>>T;
        while(T--){
            int n,m;
            cin>>n>>m;
            memset(G,0,sizeof(G));
            memset(dp,0,sizeof(dp));
            memset(way,0,sizeof(way));
            for(int i=0;i<n;i++)  cin>>V[i];
            for(int i=0;i<m;i++){
                int x,y;
                cin>>x>>y;
                G[x-1][y-1] = 1;
                G[y-1][x-1] = 1;
            }
            if(n == 1){
                printf("%d 1
    ",V[0]);
                continue;
            }
            for(int i=0;i<n;i++)
                for(int j=i+1;j<n;j++){
                    if(G[i][j]){
                        dp[i][j][(1<<i)|(1<<j)] = V[i] + V[j] + V[i]*V[j];
                        dp[j][i][(1<<i)|(1<<j)] = V[i] + V[j] + V[i]*V[j]; //先处理相邻的两点的;
                        way[i][j][(1<<i)|(1<<j)] = 1;
                        way[j][i][(1<<i)|(1<<j)] = 1;
                    }
                }
            int All = (1<<n) - 1;
            for(int S = 3;S <= All; S++){  //在每个状态下枚举状态内的点i,j,扩展出节点k.挺暴力的。
                for(int i=0;i<n;i++){
                    if(!(1<<i & S)) continue;
                    for(int j=0;j<n;j++){
                        if(!(1<<j & S) || i == j || !dp[i][j][S]) continue;
                        for(int k=0;k<n;k++){
                            if((1<<k)&S || !G[j][k])    continue;
                            int r = S + (1<<k);
                            ll_int q = dp[i][j][S] + V[k] + V[j]*V[k];
                            if(G[i][k]){
                                q += V[i]*V[j]*V[k];
                            }
                            if(q > dp[j][k][r]){
                                dp[j][k][r] = q;
                                way[j][k][r] = way[i][j][S];
                            }
                            else if(q == dp[j][k][r]){
                                way[j][k][r] += way[i][j][S];
                            }
                        }
                    }
                }
            }
            ll_int ans,answay;
            ans = 0; answay = 0;
            for(int i=0;i<n;i++)
                for(int j=0;j<n;j++){
                   if(i!=j){
                      if(dp[i][j][All] > ans){
                         ans = dp[i][j][All];
                         answay = way[i][j][All];
                      }
                      else if(dp[i][j][All] == ans ){
                         answay += way[i][j][All];
                      }
                   }
            }
            if(ans == 0)  printf("0 0
    ");
            else
                printf("%I64d %I64d
    ",ans,answay/2);
    
        }
    }
    View Code
  • 相关阅读:
    AcWing 125. 耍杂技的牛
    AcWing 148. 合并果子
    AcWing 907. 区间覆盖
    AcWing 908. 最大不相交区间数量
    AcWing 906. 区间分组
    AcWing 905. 区间选点
    AcWing 285. 没有上司的舞会
    AcWing 1049. 大盗阿福
    AcWing 901. 滑雪
    AcWing 91. 最短Hamilton路径
  • 原文地址:https://www.cnblogs.com/acmdeweilai/p/3297831.html
Copyright © 2020-2023  润新知