zoukankan      html  css  js  c++  java
  • P3355 骑士共存问题 二分建图 + 当前弧优化dinic

    P3355 骑士共存问题

    题意:

      也是一个棋盘,规则是“马”不能相互打到。

    思路:

      奇偶点分开,二分图建图,这道题要注意每个点可以跑八个方向,两边都可以跑,所以边 = 20 * n * n。

      然后dinic 要用当前弧优化。

    #include <algorithm>
    #include  <iterator>
    #include  <iostream>
    #include   <cstring>
    #include   <cstdlib>
    #include   <iomanip>
    #include    <bitset>
    #include    <cctype>
    #include    <cstdio>
    #include    <string>
    #include    <vector>
    #include     <stack>
    #include     <cmath>
    #include     <queue>
    #include      <list>
    #include       <map>
    #include       <set>
    #include   <cassert>
    
    using namespace std;
    #define lson (l , mid , rt << 1)
    #define rson (mid + 1 , r , rt << 1 | 1)
    #define debug(x) cerr << #x << " = " << x << "
    ";
    #define pb push_back
    #define pq priority_queue
    
    
    
    typedef long long ll;
    typedef unsigned long long ull;
    //typedef __int128 bll;
    typedef pair<ll ,ll > pll;
    typedef pair<int ,int > pii;
    typedef pair<int,pii> p3;
    
    //priority_queue<int> q;//这是一个大根堆q
    //priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q
    #define fi first
    #define se second
    //#define endl '
    '
    
    #define OKC ios::sync_with_stdio(false);cin.tie(0)
    #define FT(A,B,C) for(int A=B;A <= C;++A)  //用来压行
    #define REP(i , j , k)  for(int i = j ; i <  k ; ++i)
    #define max3(a,b,c) max(max(a,b), c);
    #define min3(a,b,c) min(min(a,b), c);
    //priority_queue<int ,vector<int>, greater<int> >que;
    
    const ll oo = 1ll<<17;
    const ll mos = 0x7FFFFFFF;  //2147483647
    const ll nmos = 0x80000000;  //-2147483648
    const int inf = 0x3f3f3f3f;
    const ll inff = 0x3f3f3f3f3f3f3f3f; //18
    const int mod = 1000000007;
    const double esp = 1e-8;
    const double PI=acos(-1.0);
    const double PHI=0.61803399;    //黄金分割点
    const double tPHI=0.38196601;
    
    
    
    template<typename T>
    inline T read(T&x){
        x=0;int f=0;char ch=getchar();
        while (ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
        while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
        return x=f?-x:x;
    }
    /*-----------------------showtime----------------------*/
                const int maxn = 209;
                int mp[maxn][maxn];
    
                struct E
                {
                    int u,v,val;
                    int nxt;                
                }edge[20 * maxn*maxn];
                int gtot = 0,head[maxn*maxn];
                void addedge(int u,int v,int val){
                    edge[gtot].u = u;
                    edge[gtot].v = v;
                    edge[gtot].val = val;
                    edge[gtot].nxt = head[u];
                    head[u] = gtot++;
    
                    edge[gtot].u = v;
                    edge[gtot].v = u;
                    edge[gtot].val = 0;
                    edge[gtot].nxt = head[v];
                    head[v] = gtot++;
                }
                int nx[8][2] = {
                    {-2,-1}, {-1,-2},{-2, 1},{-1,2},{1,-2},{2,-1},{1,2},{2,1}
                };
                int n,m;
                int cal(int i,int j){
                    return (i-1)*n + j;
                }
    
                int dis[maxn*maxn],cur[maxn*maxn];
                bool bfs(int s,int t){
                    memset(dis, inf, sizeof(dis));
                    for(int i=s; i<=t; i++) cur[i] = head[i];
                    queue<int>que;
                    que.push(s);
                    dis[s] = 0;
                    while(!que.empty()){
                        int u = que.front(); que.pop();
                        for(int i= head[u]; ~i; i = edge[i].nxt){
                            int v = edge[i].v;
                            if(edge[i].val > 0 && dis[v] > dis[u] + 1){
                                dis[v] = dis[u] + 1;
                                que.push(v);
                            }
                        }
                    }
                    return dis[t] < inf;
                }
    
                int dfs(int u,int t,int maxflow){
                    if(u == t || maxflow == 0) return maxflow;
    
                    for(int i=cur[u]; ~i; i = edge[i].nxt){
                        cur[u] = i;
                        int v = edge[i].v;
                        if(edge[i].val > 0 && dis[v] == dis[u] + 1){
                            int f = dfs(v, t, min(maxflow, edge[i].val));
                            
                            if(f > 0){
                                edge[i].val -= f;
                                edge[i^1].val += f;
                                return f;
                            }
                        }
    
                    }
                    return 0;
                }
                int dinic(int s,int t){
                    int flow = 0;
                    while(bfs(s,t)){
                        while(int f = dfs(s,t,inf)) flow += f;
                    }
                    return flow;
                }
    int main(){
                memset(head, -1, sizeof(head));
                scanf("%d%d", &n, &m);
                int s = 0, t = n*n+1;
                int sum = n * n;
                for(int i=1; i<=m; i++){
                    int x,y;
                    scanf("%d%d", &x, &y);
                    mp[x][y] = 1;
                    sum--;
                }   
                for(int i=1; i<=n; i++){
                    for(int j=1; j<=n; j++) {
                        if((i+j)% 2 == 1) {
                            if(mp[i][j]) addedge(s, cal(i,j), 0);
                            else addedge(s, cal(i, j), 1);
                        } 
                        else {
                            if(mp[i][j]) addedge(cal(i,j),t, 0);
                            else addedge(cal(i,j), t, 1);  
                        }
                    }
                }
    
                for(int i=1; i<=n; i++){
                    for(int j=1; j<=n; j++){
                            if((i+j)% 2 == 0) continue;
                            for(int k=0; k<8; k++){
                                int x = i + nx[k][0];
                                int y = j + nx[k][1];
                                if(x <1 || x > n || y < 1 || y > n) continue;
                                addedge(cal(i,j), cal(x,y),inf);
                            }
                    }
                }
                cout<<sum - dinic(s, t)<<endl;
                return 0;
    }
    View Code
  • 相关阅读:
    前端与算法 leetcode 344. 反转字符串
    JavaScript闭包使用姿势指南
    前端与算法 leetcode 48. 旋转图像
    前端与算法 leetcode 36. 有效的数独
    前端与算法 leetcode 1. 两数之和
    前端与算法 leetcode 283. 移动零
    前端与编译原理 用js去运行js代码 js2run
    前端与算法 leetcode 66. 加一
    前端与算法 leetcode 350. 两个数组的交集 II
    前端与算法 leetcode 26. 删除排序数组中的重复项
  • 原文地址:https://www.cnblogs.com/ckxkexing/p/10351814.html
Copyright © 2011-2022 走看看