제출 #896293

#제출 시각아이디문제언어결과실행 시간메모리
896293abcvuitunggio분수 공원 (IOI21_parks)C++17
70 / 100
1140 ms245044 KiB
#include "parks.h"
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int INF=1e17;
struct Edge{
    int u,v,c;
    Edge(){};
    Edge (int u, int v, int c){
        this->u=u;
        this->v=v;
        this->c=c;
    }
};
struct Dinic{
    vector <Edge> s;
    vector <vector <int>> adj;
    vector <vector <int> :: iterator> cur;
    vector <int> h;
    int n, sink, source;
    void Reset(){
        s.clear();
        adj.clear();
        cur.clear();
        h.clear();
    }
    void Assign(int n){
        this->n=n;
        s.reserve(n+2);
        adj.resize(n+2);
        cur.resize(n+2);
        h.resize(n+2);
    }
    void AddEdge(int u, int v, int c){
        s.emplace_back(u,v,c);
        adj[u].emplace_back(s.size()-1);
        s.emplace_back(v,u,0);
        adj[v].emplace_back(s.size()-1);
    }
    bool bfs(){
        fill(h.begin(),h.end(),n+2);
        queue <int> q({sink});
        h[sink]=0;
        while (!q.empty()){
            int c=q.front();
            q.pop();
            for (int i:adj[c])
                if (h[s[i].v]==n+2&&s[i^1].c){
                    h[s[i].v]=h[c]+1;
                    if (s[i].v==source)
                        return true;
                    q.emplace(s[i].v);
                }
        }
        return false;
    }
    int dfs(int v, int flowin){
        if (v==sink)
            return flowin;
        int flowout=0;
        for (;cur[v]!=adj[v].end();++cur[v]){
            int i=*cur[v];
            if (!s[i].c||h[s[i].v]+1!=h[v])
                continue;
            int q=dfs(s[i].v,min(flowin,s[i].c));
            flowout+=q;
            if (flowin!=INF)
                flowin-=q;
            s[i].c-=q;
            s[i^1].c+=q;
            if (!flowin)
                break;
        }
        return flowout;
    }
    int BlockFlow(){
        for (int i=1;i<=n;i++)
            cur[i]=adj[i].begin();
        return dfs(source,INF);
    }
    int MaxFlow(int s, int t){
        source=s;
        sink=t;
        int res=0;
        while (bfs())
            res+=BlockFlow();
        return res;
    }
}g;
int n,dx[4]={1,0,-1,0},dy[4]={0,1,0,-1},p[200001],id,order[200001];
pair <int, int> bench[400001];
map <int, int> mp[300001],mp2[300001];
vector <int32_t> px,py;
int f(int i){
    return (p[i]==i?i:p[i]=f(p[i]));
}
bool unite(int i, int j){
    i=f(i);
    j=f(j);
    if (i==j)
        return false;
    p[j]=i;
    return true;
}
int32_t construct_roads(vector <int32_t> x, vector <int32_t> y) {
    if (x.size()==1){
        build({},{},{},{});
        return 1;
    }
    vector <int32_t> u,v,a,b;
    n=x.size();
    for (int i=0;i<n;i++)
        mp[x[i]][y[i]]=i;
    iota(p,p+n,0);
    iota(order,order+n,0);
    px=x,py=y;
    sort(order,order+n,[](int i, int j){return make_pair(px[i],py[i])<make_pair(px[j],py[j]);});
    a.assign(n-1,0);
    b.assign(n-1,0);
    while (true){
        g.Reset();
        g.Assign(n*10);
        u.clear();
        v.clear();
        id=0;
        for (int i=1;i<=300000;i+=2)
            mp2[i].clear();
        for (int it=0;it<n;it++){
            int i=order[it];
            for (int j=0;j<4;j++)
                if (mp[x[i]+dx[j]*2].count(y[i]+dy[j]*2)){
                    int k=mp[x[i]+dx[j]*2][y[i]+dy[j]*2];
                    if (unite(i,k)){
                        u.push_back(i);
                        v.push_back(k);
                        g.AddEdge(n*3-1,u.size(),1);
                        int X=x[i]+dx[j],Y=y[i]+dy[j];
                        for (int l=0;l<4;l++)
                            if (X+dx[l]!=x[i]&&Y+dy[l]!=y[i]){
                                if (!mp2[X+dx[l]].count(Y+dy[l])){
                                    id++;
                                    mp2[X+dx[l]][Y+dy[l]]=id;
                                    bench[id]={X+dx[l],Y+dy[l]};
                                    g.AddEdge(id+n-1,n*3,1);
                                }
                                g.AddEdge(u.size(),mp2[X+dx[l]][Y+dy[l]]+n-1,1);
                            }
                    }
                }
        }
        if (u.size()<n-1)
            return 0;
        int mx=g.MaxFlow(n*3-1,n*3);
        if (mx<n-1){
            random_shuffle(order,order+n);
            continue;
        }
        for (int i=0;i<g.s.size();i+=2)
            if (!g.s[i].c&&g.s[i].u!=n*3-1&&g.s[i].v!=n*3){
                a[g.s[i].u-1]=bench[g.s[i].v-n+1].first;
                b[g.s[i].u-1]=bench[g.s[i].v-n+1].second;
            }
        build(u,v,a,b);
        return 1;
    }
}

컴파일 시 표준 에러 (stderr) 메시지

parks.cpp: In function 'int32_t construct_roads(std::vector<int>, std::vector<int>)':
parks.cpp:151:21: warning: comparison of integer expressions of different signedness: 'std::vector<int>::size_type' {aka 'long unsigned int'} and 'long long int' [-Wsign-compare]
  151 |         if (u.size()<n-1)
      |             ~~~~~~~~^~~~
parks.cpp:158:23: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<Edge>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  158 |         for (int i=0;i<g.s.size();i+=2)
      |                      ~^~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...