zoukankan      html  css  js  c++  java
  • 2019ICPC邀请赛南昌A Attack 斯坦纳树

    先对8个点整体做斯坦纳树,再求出每个状态的最小代价。再看每个状态是否属于独立的,即包含的点都是成对的,我们去更新这些独立的状态即可。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <string>
      4 #include <map>
      5 #include <queue>
      6 #include <iostream>
      7 using namespace std;
      8 const int MAXN = 40,MAXM = 2100;
      9 queue <int> que;
     10 string s1,s2;
     11 map <string,int> mp;
     12 bool inq[MAXN];
     13 int head[MAXN],dis[MAXN][1 << 8],ans[1 << 8],spe[1 << 8],to[MAXM],nxt[MAXM],val[MAXM];
     14 int cnt,n,m,s,t,inf;
     15 void add(int x,int y,int v)
     16 {
     17     nxt[++cnt] = head[x];
     18     to[cnt] = y;
     19     val[cnt] = v;
     20     head[x] = cnt;
     21 }
     22 void SPFA(int o)
     23 {
     24     while(!que.empty())
     25     {
     26         int t = que.front();
     27         que.pop();
     28         inq[t] = false;
     29         for(int i = head[t];i;i = nxt[i])
     30         {
     31             if(dis[to[i]][o] > dis[t][o] + val[i])
     32             {
     33                 dis[to[i]][o] = dis[t][o] + val[i];
     34                 if(!inq[to[i]])
     35                 {
     36                     inq[to[i]] = true;
     37                     que.push(to[i]);
     38                 }
     39             }
     40         }
     41     }
     42 }
     43 void steiner_tree()
     44 {
     45     for (int i = 0;i < (1 << 8);i++)
     46     {
     47         for (int j = 1;j <= n;j++)
     48         {
     49             for (int k = i;k;k = (k - 1) & i)
     50                 dis[j][i] = min(dis[j][i],dis[j][k] + dis[j][i - k]);
     51             if (dis[j][i] != inf)
     52             {
     53                 que.push(j);
     54                 inq[j] = true;
     55             }
     56         }
     57         SPFA(i);
     58     }
     59 }
     60 bool check(int o)
     61 {
     62     for (int i = 0;i <= 7;i += 2)
     63         if (((o >> i) & 1) ^ ((o >> (i + 1)) & 1))
     64             return false;
     65     return true;
     66 }
     67 int main()
     68 {
     69     while (scanf("%d%d",&n,&m) > 0)
     70     {
     71         cnt = 0;
     72         memset(head,0,sizeof(head));
     73         memset(nxt,0,sizeof(nxt)); 
     74         memset(dis,0x1f,sizeof(dis));
     75         memset(ans,0x1f,sizeof(ans)); 
     76         inf = ans[0];
     77         int tv;
     78         string s1,s2;
     79         for (int i = 1;i <= n;i++)
     80         {
     81             cin >> s1;
     82             mp[s1] = i;
     83         }
     84         for (int i = 1;i <= m;i++)
     85         {
     86             cin >> s1 >> s2;
     87             scanf("%d",&tv);
     88             add(mp[s1],mp[s2],tv);
     89             add(mp[s2],mp[s1],tv);
     90         }
     91         for (int i = 1;i <= 8;i++)
     92         {
     93             cin >> s1;
     94             dis[mp[s1]][1 << (i - 1)] = 0;
     95         }
     96         steiner_tree();
     97         for (int i = 0;i < (1 << 8);i++)
     98         {
     99             spe[i] = check(i);
    100             for (int j = 1;j <= n;j++)
    101                 ans[i] = min(ans[i],dis[j][i]); 
    102         }
    103         for (int i = 0;i < (1 << 8);i++)
    104             if (spe[i])
    105                 for (int j = i;j;j = (j - 1) & i)
    106                     if (spe[j] && spe[i - j])
    107                         ans[i] = min(ans[i],ans[j] + ans[i - j]);
    108         printf("%d
    ",ans[(1 << 8) - 1]);
    109     }
    110     return 0;
    111 }
  • 相关阅读:
    Regionals 2012 :: Asia
    计算几何专题
    简单几何(凸包+多边形面积) POJ 3348 Cows
    简单几何(求凸包点数) POJ 1228 Grandpa's Estate
    简单几何(凸包+枚举) POJ 1873 The Fortified Forest
    简单几何(极角排序) POJ 2007 Scrambled Polygon
    Codeforces Round #328 (Div. 2)
    简单几何(直线求交点) POJ 2074 Line of Sight
    简单几何(点的位置) POJ 1584 A Round Peg in a Ground Hole
    简单几何(线段相交)+模拟 POJ 3449 Geometric Shapes
  • 原文地址:https://www.cnblogs.com/iat14/p/12441165.html
Copyright © 2011-2022 走看看