zoukankan      html  css  js  c++  java
  • [BeiJing wc2012]连连看

    题目链接 费用流板子+拆点

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 inline int read()
      5 {
      6     int x=0,f=1;char ch=getchar();
      7     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
      8     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
      9     return x*f;
     10 }
     11 
     12 
     13 /********************************************************************/
     14 
     15 struct ZKM_MinCostMaxFlow{
     16     const static int maxn = 1e5+50;
     17     const static int maxE = 1e5+50;
     18     const static int INF = 0xfffffff;
     19 
     20     struct Edge{
     21         int to, next, cap, flow, cost;
     22         Edge(int _to = 0, int _next = 0, int _cap = 0, int _flow = 0, int _cost = 0):
     23             to(_to), next(_next), cap(_cap), flow(_flow), cost(_cost){}
     24     }edge[maxE*2];
     25 
     26     int head[maxn], tot;
     27     int cur[maxn], dis[maxn];
     28     bool vis[maxn];
     29     int ss, tt, N;
     30     int min_cost, max_flow;
     31     void init(int N){
     32         tot = 0;
     33         for(int i = 0;i < N;i++) head[i] = -1;
     34     }
     35     int addedge(int u, int v, int cap, int cost){
     36         edge[tot] = Edge(v, head[u], cap, 0, cost);
     37         int rs = tot;
     38         head[u] = tot++;
     39         edge[tot] = Edge(u, head[v], 0, 0, -cost);
     40         head[v] = tot++;
     41         return rs;
     42     }
     43     int aug(int u, int flow){
     44         if(u == tt) return flow;
     45         vis[u] = true;
     46         for(int i = cur[u];i != -1;i = edge[i].next){
     47             int v = edge[i].to;
     48             if(edge[i].cap > edge[i].flow && !vis[v] && dis[u] == dis[v] + edge[i].cost){
     49                 int tmp = aug(v, min(flow, edge[i].cap - edge[i].flow));
     50                 edge[i].flow += tmp;
     51                 edge[i^1].flow -= tmp;
     52                 cur[u] = i;
     53                 if(tmp) return tmp;
     54             }
     55         }
     56         return 0;
     57     }
     58     bool modify_label(){
     59         int d = INF;
     60         for(int u = 0;u < N;u++){
     61             if(vis[u]){
     62                 for(int i = head[u];i != -1;i = edge[i].next){
     63                     int v = edge[i].to;
     64                     if(edge[i].cap > edge[i].flow && !vis[v]){
     65                         d = min(d, dis[v]+edge[i].cost - dis[u]);
     66                     }
     67                 }
     68             }
     69         }
     70         if(d == INF) return false;
     71         for(int i = 0;i < N;i++){
     72             if(vis[i]){
     73                 vis[i] = false;
     74                 dis[i] += d;
     75             }
     76         }
     77         return true;
     78     }
     79 
     80     pair<int, int> mincostmaxflow(int start, int ed, int n){
     81         ss = start, tt = ed, N = n;
     82         min_cost = max_flow = 0;
     83         for(int i = 0;i < n;i++) dis[i] = 0;
     84         while(1){
     85             for(int i = 0;i < n;i++) cur[i] = head[i];
     86             while(1){
     87                 for(int i = 0;i < n;i++) vis[i] = false;
     88                 int tmp = aug(ss, INF);
     89                 if(tmp == 0) break;
     90                 max_flow += tmp;
     91                 min_cost += tmp*dis[ss];
     92             }
     93             if(!modify_label()) break;
     94         }
     95         return make_pair( max_flow, min_cost );
     96     }
     97 }solver;
     98 
     99 int gcd(int x, int y){
    100     if(y == 0) return x;
    101     else return gcd(y, x%y);
    102 }
    103 
    104 bool check(int x, int y){
    105     if(x == y) return false;
    106     if(x < y)  swap(x, y);
    107     int t = sqrt(x*x-y*y);
    108     if(t*t != x*x-y*y) return false;
    109     if(gcd(y, t) != 1) return false;
    110     return true;
    111 }
    112 
    113 int main(){
    114     int a, b;
    115     a = read(); b = read();
    116     solver.init(b*2+5);
    117     for(int i = a;i <= b;i++){
    118         for(int j = a;j <= b;j++){
    119             if(check(i, j)){
    120                 solver.addedge(i, j+b, 1, -i-j);
    121             }
    122         }
    123         solver.addedge(b*2+1, i, 1, 0);     //拆点
    124         solver.addedge(i+b, b*2+2, 1, 0);   //拆点
    125     }
    126     pair<int, int> ans = solver.mincostmaxflow(b*2+1, b*2+2, b*2+5);
    127     printf("%d %d
    ", ans.first/2, -ans.second/2);
    128     return 0;
    129 }
  • 相关阅读:
    jforum二次开发教程
    gitPermission denied (publickey).
    用keytool创建Keystore和Trustsotre文件只需五步
    导入数据库时报错1067 – Invalid default value for ‘字段名’
    WordPress用户角色及其权限管理编辑插件:User Role Editor汉化版
    http://blog.csdn.net/wh211212/article/details/53005321
    centos 安装 mysql
    卸载apache服务
    Cordova插件相关常用命令
    UI 交互
  • 原文地址:https://www.cnblogs.com/ouyang_wsgwz/p/9756779.html
Copyright © 2011-2022 走看看