码迷,mamicode.com
首页 > 其他好文 > 详细

[XSY 1557] task

时间:2017-08-24 15:30:39      阅读:213      评论:0      收藏:0      [点我收藏+]

标签:main   运算   bfs   false   lib   opera   inline   oid   加法   

分析

  定义五元组上的零, 加法运算, 以及全序关系.

  用最小割求解最大权闭合图.

 

实现

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cstdlib>
  4 #include <cctype>
  5 #include <algorithm>
  6 using namespace std;
  7 #define F(i, a, b) for (register int i = (a); i <= (b); i++)
  8 #define P(i, a, b) for (register int i = (a); i >= (b); i--)
  9 #define LL long long
 10 inline int rd(void) {
 11     int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == -) f = -1;
 12     int x = 0; for (; isdigit(c); c = getchar()) x = x*10+c-0; return x*f;
 13 }
 14  
 15 const int N = 1005;
 16 const int M = 15000;
 17 const int INF = ~0u>>2;
 18  
 19 int n, m, K;
 20 struct Data {
 21     int a[7];
 22      
 23     inline Data(void) { memset(a, 0, sizeof a); }
 24     inline Data(char *s) { memset(a, 0, sizeof a); F(i, 1, K) a[i] = (s[i] == - ? -1 : s[i] == / ? 0 : +1); }
 25      
 26     inline Data operator - (void) {
 27         Data Ret;
 28         F(i, 1, K)
 29             Ret.a[i] = -a[i];
 30         return Ret;
 31     }
 32     friend inline Data operator + (Data A, Data B) {
 33         Data Ret;
 34         F(i, 1, K)
 35             Ret.a[i] = A.a[i] + B.a[i];
 36         return Ret;
 37     }
 38     friend inline Data operator - (Data A, Data B) { return A + (-B); }
 39      
 40     friend inline bool operator < (Data A, Data B) {
 41         F(i, 1, K)
 42             if (A.a[i] != B.a[i])
 43                 return A.a[i] < B.a[i];
 44         return false;
 45     }
 46     friend inline bool operator > (Data A, Data B) {
 47         F(i, 1, K)
 48             if (A.a[i] != B.a[i])
 49                 return A.a[i] > B.a[i];
 50         return false;
 51     }
 52     friend inline bool operator == (Data A, Data B) {
 53         F(i, 1, K)
 54             if (A.a[i] != B.a[i])
 55                 return false;
 56         return true;
 57     }
 58 }key[N], sum, Max, Emp; 
 59  
 60 int fs, ft, siz;
 61 struct Edge { int v, nx; Data f; }mp[M]; int tot, hd[N];
 62 inline void Init(int x, int y, Data f) {
 63     mp[++tot] = (Edge){y, hd[x], f}, hd[x] = tot;
 64     mp[++tot] = (Edge){x, hd[y], Emp}, hd[y] = tot;
 65 }
 66  
 67 int q[N], qh, qt, Lev[N];
 68 bool BFS(void) {
 69     memset(q, 0, sizeof q), qh = qt = 0, memset(Lev, -1, sizeof Lev);
 70     q[++qt] = fs, Lev[fs] = 0;
 71     while (qh != qt) {
 72         int x = q[++qh];
 73         for (int k = hd[x]; k > 0; k = mp[k].nx)
 74             if (mp[k].f > Emp && Lev[mp[k].v] == -1) {
 75                 Lev[mp[k].v] = Lev[x]+1;
 76                 if (mp[k].v == ft) return true;
 77                 q[++qt] = mp[k].v;
 78             }
 79     }
 80     return false;
 81 }
 82 Data DFS(int x, Data flow) {
 83     if (x == ft) return flow;
 84     Data sum;
 85     for (int k = hd[x]; k > 0; k = mp[k].nx)
 86         if (mp[k].f > Emp && Lev[x]+1 == Lev[mp[k].v]) {
 87             Data t = DFS(mp[k].v, min(flow, mp[k].f));
 88             if (t > Emp) {
 89                 mp[k].f = mp[k].f - t, mp[k^1].f = mp[k^1].f + t;
 90                 sum = sum + t, flow = flow - t;
 91                 if (flow == Emp) break;
 92             }
 93             else Lev[mp[k].v] = siz+2;
 94         }
 95     return sum;
 96 }
 97  
 98 int main(void) {
 99     #ifndef ONLINE_JUDGE
100         freopen("task.in", "r", stdin);
101     #endif
102      
103     char s[10];
104     n = rd(), m = rd(), K = rd();
105     F(i, 1, n) {
106         scanf("%s", s+1);
107         key[i] = Data(s);
108     }
109     F(i, 1, K) Max.a[i] = INF;
110      
111     siz = n, fs = ++siz, ft = ++siz, tot = 1;
112     F(i, 1, n)
113         if (key[i] < Data())
114             Init(i, ft, -key[i]);
115         else Init(fs, i, key[i]), sum = sum + key[i];
116     F(i, 1, m) {
117         int x = rd(), y = rd();
118         Init(x, y, Max);
119     }
120      
121     while (BFS())
122         sum = sum - DFS(fs, Max);
123     F(i, 1, K)
124         printf("%d ", 1000 + sum.a[i]);
125     puts("");
126      
127     return 0;
128 }

 

[XSY 1557] task

标签:main   运算   bfs   false   lib   opera   inline   oid   加法   

原文地址:http://www.cnblogs.com/Sdchr/p/7423236.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!