zoukankan      html  css  js  c++  java
  • 【TJOI2014】匹配

    题面

    https://www.luogu.org/problem/P3967

    题解

    二分图上求可能/必然割边,由于当时还非常弱,不会用$tarjan$,所以是把边删去重跑一次的。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<vector>
    #include<algorithm>
    #include<cassert>
    #include<queue>
    #define ri register int
    #define N 500
    #define INF 1000000007
    using namespace std;
    int n;
    vector<int> id[N*5];
    int w[2*N*N+4*N],tw[2*N*N+4*N],c[2*N*N+4*N],to[2*N*N+4*N],dis[N*5];
    int start[2*N*N+4*N];
    bool check[2*N*N+4*N];
    int used[N*5];
    
    int ans=0,cnt=-1;
    bool vis[N*5];
    int fro[N*5],cut[N*5],tot=0,con=0;
    
    struct node {
      int a,b;
      bool operator < (const node &rhs) const {
        return a<rhs.a;
      }
    } sy[N*5];
    
    void addedge(int u,int v,int co,int wo) {
      ++cnt; id[u].push_back(cnt); c[cnt]=co;  tw[cnt]=wo; to[cnt]=v; start[cnt]=u;
      ++cnt; id[v].push_back(cnt); c[cnt]=-co; tw[cnt]=0;  to[cnt]=u; start[cnt]=v;
    }
    queue<int> q;
    
    bool spfa() {
      memset(vis,0,sizeof(vis));
      for (ri i=0;i<=2*n;i++) dis[i]=-INF;
      dis[(2*n+1)]=0;
      while (!q.empty()) q.pop();
      q.push((2*n+1)); 
      vis[(2*n+1)]=1;
      while (!q.empty()) {
        int x=q.front(); q.pop(); vis[x]=0;
        for (ri i=0;i<id[x].size();i++) {
          int e=id[x][i];
          if (w[1^e] && dis[to[e]]<dis[x]-c[e]) {
            dis[to[e]]=dis[x]-c[e];
            if (!vis[to[e]]) vis[to[e]]=1,q.push(to[e]);
          }
        }
      }
      return dis[0]>-INF;
    }
    
    int dfs(int x,int limit) {
      vis[x]=1;
      if (x==(2*n+1)||(!limit)) return limit;
      int get=0;
      for (ri i=used[x];i<id[x].size();i++) {
        int e=id[x][i];
        if (dis[x]-c[e]==dis[to[e]] && !vis[to[e]] && w[e]) {
          int t=dfs(to[e],min(limit,w[e]));
          if (!t) continue;
          get+=t;limit-=t;
          w[e]-=t,w[1^e]+=t;
          used[x]=i;
          if (!limit) return get;
        }
      }
      return get;
    }
    
    void init() {
      for (ri i=0;i<=cnt;i++) w[i]=tw[i];
    }
    
    void zkw(int opt) {
      while(spfa()) {
        vis[(2*n+1)]=1;
        while (vis[(2*n+1)]) {
          memset(vis,0,sizeof(vis));
          memset(used,0,sizeof(used));
          if (opt) ans+=dfs(0,INF)*dis[0];
          else con+=dfs(0,INF)*dis[0];
        }
      }
    }
    
    int main() {
      scanf("%d",&n);
      for (ri i=1;i<=n;i++) {
        for (ri j=1;j<=n;j++) {
          int co;
          scanf("%d",&co);
          addedge(i,n+j,co,1);
        }
      }
      for (ri i=1;i<=n;i++) addedge(0,i,0,1);
      for (ri i=n+1;i<=2*n;i++) addedge(i,(2*n+1),0,1);
      init();zkw(1);
      printf("%d
    ",ans);
      int cc=0;
      for (ri i=0;i<=cnt;i+=2) {
        if (!w[i] && start[i]>=1 && start[i]<=n && to[i]>=n+1 && to[i]<=2*n) check[i]=1;
      }
      for (ri i=0;i<=cnt;i+=2) if (check[i]) {
        init();
        w[i]=0; w[1^i]=0;
        con=0;
        zkw(0);
        //printf("%d
    ",con);
        if (con!=ans) {
          sy[++cc]=(node){start[i],to[i]};
        }
      }
      sort(sy+1,sy+cc+1);
      for (ri i=1;i<=cc;i++) printf("%d %d
    ",sy[i].a,sy[i].b-n);
    }
  • 相关阅读:
    leetcode701. Insert into a Binary Search Tree
    leetcode 958. Check Completeness of a Binary Tree 判断是否是完全二叉树 、222. Count Complete Tree Nodes
    leetcode 110. Balanced Binary Tree
    leetcode 104. Maximum Depth of Binary Tree 111. Minimum Depth of Binary Tree
    二叉树
    leetcode 124. Binary Tree Maximum Path Sum 、543. Diameter of Binary Tree(直径)
    5. Longest Palindromic Substring
    128. Longest Consecutive Sequence
    Mac OS下Android Studio的Java not found问题,androidfound
    安卓 AsyncHttpClient
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11426780.html
Copyright © 2011-2022 走看看