tjut 3435

来源:互联网 发布:截断数据库日志 编辑:程序博客网 时间:2024/06/07 03:08
#include<iostream>  #include<cstdio>  #include<cstring>  #include<cmath>  #include<algorithm>  using namespace std;  #define N 1010  #define MAXN 1<<28  #define CLR(arr, what) memset(arr, what, sizeof(arr))  int map[N][N];  int lx[N], ly[N];  bool visitx[N], visity[N];  int slack[N];  int match[N];  int n;    bool Hungary(int u)  {      int temp;      visitx[u] = true;      for(int i = 1; i <= n; ++i)      {          if(visity[i])              continue;          else          {              temp = lx[u] + ly[i] - map[u][i];              if(temp == 0) //相等子图              {                  visity[i] = true;                  if(match[i] == -1 || Hungary(match[i]))                  {                      match[i] = u;                      return true;                  }              }              else //松弛操作                  slack[i] = min(slack[i], temp);          }      }      return false;  }    void KM_perfect_match()  {      int temp;      CLR(ly, 0);      for(int i = 1; i <= n; ++i) //定标初始化          lx[i] = -MAXN;      for(int i = 1; i <= n; ++i)          for(int j = 1; j <= n; ++j)              lx[i] = max(lx[i], map[i][j]);      for(int i = 1; i <= n; ++i)      {          for(int j = 1; j <= n; ++j)              slack[j] = MAXN;          while(1)          {              CLR(visitx, 0);              CLR(visity, 0);              if(Hungary(i))                  break;              else              {                  temp = MAXN;                  for(int j = 1; j <= n; ++j)                      if(!visity[j])                          temp = min(temp, slack[j]);                  for(int j = 1; j <= n; ++j)                  {                      if(visitx[j])                          lx[j] -= temp;                      if(visity[j])                          ly[j] += temp;                      else                          slack[j] -= temp;                  }              }          }      }  }    int main()  {      int ncase, T = 1;      int edge;      int start, end, cost;      int answer;      bool perfect;      scanf("%d", &ncase);      while(ncase--)      {          CLR(match, -1);          answer = 0;          perfect = true;          scanf("%d%d", &n, &edge);          for(int i = 1; i <= n; ++i)              for(int j = 1; j <= n; ++j)                  map[i][j] = -MAXN;          for(int i = 0; i < edge; ++i)          {              scanf("%d%d%d", &start, &end, &cost);              if( -cost > map[start][end])                  map[start][end] = map[end][start] = -cost;          }          KM_perfect_match();          for(int i = 1; i <= n; ++i)          {              if(match[i] == - 1 || map[ match[i] ][i] == -MAXN)              {                  perfect = false;                  break;              }              answer += map[ match[i] ][i];          }          if(perfect)              printf("Case %d: %d\n", T++, -answer);          else              printf("Case %d: NO\n", T++);      }      return 0;  }  

0 0