• hdu 4085 Peach Blossom Spring


    Peach Blossom Spring

    题意:有n个城市,m条路,[1,k]的城市有居民, [n-k+1, n]的城市有庇护所, 现在要修路, 使得每一座城市的居民都可以到达一个庇护所, 并且一个庇护所只能容纳一个城市的居民, 现在求所有城市的居民都能到达庇护所的最小花费。

    题解:斯坦纳树跑出花费。 d[i][state] = cost, i代表的是第i个城市, state代表的是联通的状态, val代表的是花费。

    先跑出所有的d[i][state]的花费。然后由于不需要是联通图, 再最后跑出每种符合的最小花费。

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
      4 #define LL long long
      5 #define ULL unsigned LL
      6 #define fi first
      7 #define se second
      8 #define pb push_back
      9 #define lson l,m,rt<<1
     10 #define rson m+1,r,rt<<1|1
     11 #define max3(a,b,c) max(a,max(b,c))
     12 #define min3(a,b,c) min(a,min(b,c))
     13 typedef pair<int,int> pll;
     14 const int inf = 0x3f3f3f3f;
     15 const LL INF = 0x3f3f3f3f3f3f3f3f;
     16 const LL mod =  (int)1e9+7;
     17 const int N = 55, M = 2005;
     18 int head[N], nt[M], to[M], ct[M], tot;
     19 int d[N][1<<10], s[N], vis[N][1<<10], dp[1<<10];
     20 int n, m, k, nn;
     21 void init(){
     22     memset(head, -1, sizeof(head));
     23     memset(s, 0, sizeof(s));
     24     tot = 0;
     25 }
     26 inline void add(int u, int v, int w){
     27     to[tot] = v;
     28     ct[tot] = w;
     29     nt[tot] = head[u];
     30     head[u] = tot++;
     31 }
     32 void input(){
     33     int u, v, c;
     34     for(int i = 1; i <= m; i++){
     35         scanf("%d%d%d", &u, &v, &c);
     36         add(u, v, c);
     37         add(v, u, c);
     38     }
     39     for(int i = 1; i <= n; i++)
     40         for(int j = 0; j < nn; j++) d[i][j] = inf;
     41     for(int i = 1; i <= k; i++){
     42         s[i] = 1<<(i-1); d[i][s[i]] = 0;
     43         s[n-i+1] = 1<<(k+i-1), d[n-i+1][s[n-i+1]] = 0;
     44     }
     45 }
     46 queue<int> q;
     47 inline bool update(int x, int y, int w){
     48     if(d[x][y] <= w) return false;
     49     d[x][y] = w;
     50     return true;
     51 }
     52 void spfa(){
     53     int t, x, y;
     54     while(!q.empty()){
     55         t = q.front();
     56         q.pop();
     57         x = t / 10000, y = t%10000;
     58         vis[x][y] = 0;
     59         for(int i = head[x]; ~i; i = nt[i]){
     60             if(update(to[i],y|s[to[i]],d[x][y]+ct[i]) && y == (y|s[to[i]]) && !vis[to[i]][y]){
     61                 vis[to[i]][y] = 1;
     62                 q.push(to[i]*10000+y);
     63             }
     64         }
     65     }
     66 }
     67 bool check(int x){
     68     int r = 0;
     69     for(int i = 0;x;i++, x>>=1)
     70         r += (x&1)*(i<k?1:-1);
     71     return r==0;
     72 }
     73 void solve(){
     74     for(int i = 0; i < nn; i++){
     75         for(int j = 1; j <= n; j++){
     76             for(int k = (i-1)&i; k; k = (k-1)&i)
     77                 d[j][i] = min(d[j][i], d[j][k|s[j]]+d[j][s[j]|(i-k)]);
     78             if(d[j][i] < inf) q.push(i+j*10000), vis[j][i] = 1;
     79         }
     80         spfa();
     81     }
     82     for(int i = 0; i < nn; i++){
     83         dp[i] = inf;
     84         for(int j = 1; j <= n; j++) dp[i] = min(dp[i], d[j][i]);
     85     }
     86     for(int i = 1; i < nn; i++){
     87         if(check(i)){
     88             for(int j = i&(i-1); j; j = (j-1)&i){
     89                 if(check(j)) dp[i] = min(dp[i], dp[j]+dp[i-j]);
     90             }
     91         }
     92     }
     93     if(dp[nn-1]>=inf) puts("No solution");
     94     else printf("%d
    ", dp[nn-1]);
     95 }
     96 int main(){
     97     int t, u, v, c;
     98     scanf("%d", &t);
     99     while(t--){
    100         init();
    101         scanf("%d%d%d", &n, &m, &k);
    102         nn = 1<<(2*k);
    103         input();
    104         solve();
    105     }
    106     return 0;
    107 }
    View Code
  • 相关阅读:
    【VS开发】CListCtrl控件使用方法总结
    【VS开发】CListCtrl控件使用方法总结
    【VS开发】CTabView多页卡界面
    【VS开发】CTabView多页卡界面
    【VS开发】关于在CFormView中实现CListCtrl控件的注意事项
    【VS开发】关于在CFormView中实现CListCtrl控件的注意事项
    【VS开发】list控件的InsertColumn方法出错
    【VS开发】list控件的InsertColumn方法出错
    【VS开发】CListCtrl控件使用
    【VS开发】CListCtrl控件使用
  • 原文地址:https://www.cnblogs.com/MingSD/p/9346151.html
Copyright © 2020-2023  润新知