• poj1149 PIGS


    传送门

    优化建图的起点题...

    (好像是邱神讲的第一道网络流?)

    然后做的时候完全忘了怎么建图

    起手思路是

    1.猪圈连源点,顾客连汇点,边权分别是猪数和购买力

    2.每个猪圈向第一个顾客连边(inf)

    3.持有同一把钥匙顾客之间连边(inf)

    然后考虑所有的猪圈向外只有一个inf

    所以这一倍的点可以缩掉 直接顾客连源点就行了

    Code:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<queue>
      4 #include<iostream>
      5 #include<algorithm>
      6 #define ms(a,b) memset(a,b,sizeof a)
      7 #define rep(i,a,n) for(int i = a;i <= n;i++)
      8 #define per(i,n,a) for(int i = n;i >= a;i--)
      9 #define inf 2147483647
     10 using namespace std;
     11 typedef long long ll;
     12 typedef double D;
     13 #define eps 1e-8
     14 ll read() {
     15     ll as = 0,fu = 1;
     16     char c = getchar();
     17     while(c < '0' || c > '9') {
     18         if(c == '-') fu = -1;
     19         c = getchar();
     20     }
     21     while(c >= '0' && c <= '9') {
     22         as = as * 10 + c - '0';
     23         c = getchar();
     24     }
     25     return as * fu;
     26 }
     27 const int N = 1005;
     28 //head
     29 int n,m;
     30 int s = N-2,t = N-1;
     31 int head[N],nxt[100005],mo[100005],cst[100005],cnt = 1;
     32 void _add(int x,int y,int w) {
     33     mo[++cnt] = y;
     34     cst[cnt] = w;
     35     nxt[cnt] = head[x];
     36     head[x] = cnt;
     37 }
     38 void add(int x,int y,int w) {
     39     if(x^y) _add(x,y,w),_add(y,x,0);
     40 }
     41 
     42 int dep[N],cur[N];
     43 bool bfs() {
     44     queue<int> q;
     45     memcpy(cur,head,sizeof cur);
     46     ms(dep,0),q.push(s),dep[s] = 1;
     47     while(!q.empty()) {
     48         int x = q.front();
     49         q.pop();
     50         for(int i = head[x];i;i = nxt[i]) {
     51             int sn = mo[i];
     52             if(!dep[sn] && cst[i]) {
     53                 dep[sn] = dep[x] + 1;
     54                 q.push(sn);
     55             }
     56         }
     57     }
     58     return dep[t];
     59 }
     60 
     61 int dfs(int x,int flow) {
     62     if(x == t || flow == 0) return flow;
     63     int res = 0;
     64     for(int &i = cur[x];i;i = nxt[i]) {
     65         int sn = mo[i];
     66         if(dep[sn] == dep[x] + 1 && cst[i]) {
     67             int d = dfs(sn,min(cst[i],flow - res));
     68             if(d) {
     69                 cst[i] -= d,cst[i^1] += d;
     70                 res += d;
     71                 if(res == flow) break;
     72             }
     73         }
     74     }
     75     if(res ^ flow) dep[x] = 0;
     76     return res;
     77 }
     78 
     79 int DINIC() {
     80     int ans = 0;
     81     while(bfs()) ans += dfs(s,inf);
     82     return ans;
     83 }
     84 
     85 int a[N],fir[N];
     86 int val[N];
     87 //fir表示第一个打开猪圈i的顾客
     88 void init() {
     89     m = read();
     90     n = read();
     91     ms(head,0),ms(fir,0),ms(val,0);
     92     rep(i,1,m) a[i] = read();
     93     rep(i,1,n) {
     94         int X = read();
     95         rep(j,1,X) {
     96             int c = read();
     97             // printf("%d %d %d
    ",i,c,fir[c]);
     98             fir[c] ? add(fir[c],i,inf) : void(val[i] += a[c]);
     99             fir[c] = i;
    100         }
    101         add(s,i,val[i]),add(i,t,read());
    102     }
    103     printf("%d
    ",DINIC());
    104 }
    105 int main() {init();}
  • 相关阅读:
    正则表达式练习,持续更新中
    Jquery使用mouseenter和mouseleave实现鼠标经过弹出层且可以点击
    SQL查找 删除重复数据只保留一条
    TreeView(C#)无限目录树代码片段
    ora-01440:要减小精度或标度,则要修改的列必须为空
    SQL查询和删除重复字段的内容
    CodeSmith(C#)简单示例及相关小知识
    MSSQL 自定义函数详解
    一些精妙的sql语句收集
    134.Gas Station
  • 原文地址:https://www.cnblogs.com/yuyanjiaB/p/10011094.html
Copyright © 2020-2023  润新知