zoukankan      html  css  js  c++  java
  • HDU-1853 Cyclic Tour

    HDU-1853

    题意:有n个城市, m条单向路, 这个路有长度, 现在需要将这n个城市分成几个环, 这几个环不能有相交的城市, 求出最小的总长度。

    题解:在一个单项环中,每个城市都只会被一条路指到,所以用KM算法跑出最小费用就好了。

    注意的就是题目会给出重边。

    代码:

     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 = 110;
    18 int val[N][N];
    19 int lx[N], ly[N], match[N];
    20 int visx[N], visy[N];
    21 int slack[N];
    22 int n, m;
    23 void init(){
    24     memset(match, -1, sizeof(match));
    25     memset(ly, 0, sizeof(ly));
    26     //memset(lx, -inf, sizeof(lx));
    27     //memset(val, -inf, sizeof(val));
    28     for(int i = 1; i <= n; i++){
    29         lx[i] = -inf;
    30         for(int j = 1; j <= n; j++)
    31             val[i][j] = -inf;
    32     }
    33 
    34 }
    35 bool hunger(int u){
    36     visx[u] = 1;
    37     for(int i = 1; i <= n; i++){
    38         if(visy[i] || val[u][i] == -inf) continue;
    39         else {
    40             if(lx[u] + ly[i] == val[u][i]){
    41                 visy[i] = 1;
    42                 if(match[i] == -1 || hunger(match[i])){
    43                     match[i] = u;
    44                     return true;
    45                 }
    46             }
    47             else slack[i] = min(slack[i], lx[u]+ly[i] - val[u][i]);
    48         }
    49     }
    50     return false;
    51 
    52 }
    53 int KM_perferct_match(){
    54     /*for(int i = 1; i <= n; i++)
    55         for(int j = 1; j <= n; j++)
    56             if(val[i][j] != -inf)
    57                 lx[i] = max(lx[i], val[i][j]);*/
    58     for(int i = 1; i <= n; i++){
    59         memset(slack, inf, sizeof(slack));
    60         while(1){
    61             memset(visx, 0, sizeof(visx));
    62             memset(visy, 0, sizeof(visy));
    63             if(hunger(i)) break;
    64             else {
    65                 int tmp = inf;
    66                 for(int j = 1; j <= n; j++)
    67                     if(!visy[j]) tmp = min(tmp, slack[j]);
    68                 if(tmp == inf) return 1;
    69                 for(int j = 1; j <= n; j++){
    70                     if(visx[j]) lx[j] -= tmp;
    71                     if(visy[j]) ly[j] += tmp;
    72                 }
    73             }
    74         }
    75     }
    76     int ans = 0;
    77     for(int i = 1; i <= n; i++)
    78         if(match[i] != -1) ans += val[match[i]][i];
    79     return ans;
    80 }
    81 int main(){
    82     while(~scanf("%d%d", &n, &m)){
    83         init();
    84         while(m--){
    85             int a, b, c;
    86             scanf("%d%d%d", &a, &b, &c);
    87             val[a][b] = max(val[a][b], -c);
    88             lx[a] = max(lx[a], val[a][b]);
    89         }
    90         printf("%d
    ", -KM_perferct_match());
    91     }
    92     return 0;
    93 }
    View Code

    emm, 第一次知道, memset(a, -inf, sizeof(a)) 后 a[0] != -inf;

  • 相关阅读:
    【转】正则基础之——/b 单词边界
    【转】空格变成问号的怪问题
    【转】正则基础之——NFA引擎匹配原理
    【转】 .NET正则基础之——平衡组
    【转】正则基础之——环视
    【转】正则应用之——日期正则表达式
    【转】正则基础之——小数点
    【转】[ ] 字符组(Character Classes)
    【转】正则表达式30分钟入教程
    【转】正则基础之——非捕获组
  • 原文地址:https://www.cnblogs.com/MingSD/p/9310015.html
Copyright © 2011-2022 走看看