제출 #1193280

#제출 시각아이디문제언어결과실행 시간메모리
1193280vnedu물병 (JOI14_bottle)C++17
70 / 100
5093 ms84964 KiB
#include<bits/stdc++.h> using namespace std; typedef long long ll; template<class T> bool maximize(T &a, const T &b){ return (a < b ? a = b, 1 : 0); } template<class T> bool minimize(T &a, const T &b){ return (a > b ? a = b, 1 : 0); } #define fi first #define se second #define pb push_back #define ii pair<int, int> #define all(x) x.begin(), x.end() #define TASK "nonsense" /// end of template /// const int N = 2e3 + 10; const int P = 2e5 + 10; const int Q = 2e5 + 10; const int M = 2e5 + 10; const int inf = 1e9; struct Dsu { int n,par[M]; Dsu() {} void init(int _n) { n=_n; for(int i=1;i<=n;++i) par[i]=i; } int get(int x) { if(x==par[x]) return x; return par[x]=get(par[x]); } bool unite(int x, int y) { int s=get(x),t=get(y); if(s==t) return 0; par[s]=t; return 1; } } dsu; struct Edge { int u,v,w; Edge() {w=inf;} Edge(int u, int v, int w) : u(u),v(v),w(w) {} bool operator < (const Edge &S) const { return w<S.w; } } edge[P]; int dx[4]={1,0,-1,0}; int dy[4]={0,1,0,-1}; int n,m,_p,numQuery,numEdge=0,lo[Q],hi[Q],mid[Q],ans[Q],cur[Q],ptr,root[P]; char a[N][N]; ii p[P],query[Q]; pair<ii,ii> best[N][N]; Edge cm[P]; queue<ii> q; bool ok[Q],process[N][N]; bool cmp(int x, int y) { return mid[x]<mid[y]; } void solve() { cin>>n>>m>>_p>>numQuery; for(int i=1;i<=n;++i) { string s; cin>>s; for(int j=1;j<=m;++j) a[i][j]=s[j-1]; } for(int i=1;i<=_p;++i) { int x,y; cin>>x>>y; p[i]={x,y}; } dsu.init(_p); while(1) { int old=0; for(int i=1;i<=_p;++i) old+=(dsu.get(i)==i); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) best[i][j]={make_pair(-1,inf),make_pair(-1,inf)}; for(int i=1;i<=_p;++i) { root[i]=dsu.get(i); int x=p[i].fi,y=p[i].se; best[x][y].fi={i,0}; q.push({x,y}); } // int dpt=0; while(!q.empty()) { // ++dpt; // if(dpt==100) return; int i=q.front().fi; int j=q.front().se; q.pop(); // cout<<i<<' '<<j<<'\n'; for(int k=0;k<4;++k) { int i2=i+dx[k]; int j2=j+dy[k]; if(i2>=1 && i2<=n && j2>=1 && j2<=m && a[i2][j2]=='.') { ii cur; pair<ii,ii> &gogo=best[i2][j2]; cur=best[i][j].fi; bool ok=0; if(cur.fi!=-1) { ++cur.se; bool gg=0; if(gogo.fi.fi!=-1 && root[gogo.fi.fi]==root[cur.fi]) { if(minimize(gogo.fi.se,cur.se)) ok=1; gg=1; } if(gogo.se.fi!=-1 && root[gogo.se.fi]==root[cur.fi]) { if(minimize(gogo.se.se,cur.se)) ok=1; gg=1; } if(gg==1) { if(gogo.se.se<gogo.fi.se) swap(gogo.fi,gogo.se); } else if(cur.se<=gogo.fi.se) gogo.se=gogo.fi,gogo.fi=cur,ok=1; else if(cur.se<gogo.se.se) gogo.se=cur,ok=1; } cur=best[i][j].se; if(cur.fi!=-1) { ++cur.se; bool gg=0; if(gogo.fi.fi!=-1 && root[gogo.fi.fi]==root[cur.fi]) { if(minimize(gogo.fi.se,cur.se)) ok=1; gg=1; } if(gogo.se.fi!=-1 && root[gogo.se.fi]==root[cur.fi]) { if(minimize(gogo.se.se,cur.se)) ok=1; gg=1; } if(gg==1) { if(gogo.se.se<gogo.fi.se) swap(gogo.fi,gogo.se); } else if(cur.se<=gogo.fi.se) gogo.se=gogo.fi,gogo.fi=cur,ok=1; else if(cur.se<gogo.se.se) gogo.se=cur,ok=1; } // cout<<ok<<" "<<i2<<' '<<j2<<'\n'; if(ok) q.push({i2,j2}); } } } // return; for(int i=1;i<=_p;++i) cm[i]=Edge(); // for(int i=1;i<=n;++i) // { // for(int j=1;j<=m;++j) cout<<best[i][j].se.fi<<' '; // cout<<'\n'; // } for(int i=1;i<=_p;++i) { int x=p[i].fi,y=p[i].se; ii cur=best[x][y].se; if(cur.fi==-1) continue; // cout<<"DSAD"; Edge gaugau=Edge(i,cur.fi,cur.se); // if(gaugau.w<cm[root[i]].w) cout<<"DASD\n"; if(gaugau.w<cm[root[i]].w) cm[root[i]]=gaugau; } for(int i=1;i<=_p;++i) if(root[i]==i && cm[i].w!=inf) { int doi=root[cm[i].v]; if(dsu.get(i)!=dsu.get(doi)) { edge[++numEdge]=cm[i]; dsu.unite(i,doi); } } int cnt=0; for(int i=1;i<=_p;++i) cnt+=(dsu.get(i)==i); // cout<<old<<' '<<cnt<<'\n'; // cout<<old<<'\n'; if(old==cnt) break; } // for(int i=1;i<=numEdge;++i) // { // cout<<edge[i].u<<' '<<edge[i].v<<' '<<edge[i].w<<'\n'; // } // return; sort(edge+1,edge+1+numEdge); // int sum=0; // for(int i=1;i<=numEdge;++i) sum+=edge[i].w; // cout<<sum<<'\n'; for(int i=1;i<=numQuery;++i) { cin>>query[i].fi>>query[i].se; ans[i]=inf; lo[i]=1; hi[i]=numEdge; } for(int tri=1;tri<=20;++tri) { ptr=0; memset(ok,0,sizeof(ok)); dsu.init(_p); for(int i=1;i<=numQuery;++i) if(lo[i]<=hi[i]) { mid[i]=(lo[i]+hi[i])>>1; cur[++ptr]=i; } // break; sort(cur+1,cur+1+ptr,cmp); int num=0; for(int i=1;i<=ptr;++i) { int id=cur[i]; while(num<mid[id]) { ++num; dsu.unite(edge[num].u,edge[num].v); } ok[id]=(dsu.get(query[id].fi)==dsu.get(query[id].se)); } // break; for(int i=1;i<=numQuery;++i) if(lo[i]<=hi[i]) { if(ok[i]) ans[i]=edge[mid[i]].w,hi[i]=mid[i]-1; else lo[i]=mid[i]+1; } } for(int i=1;i<=numQuery;++i) cout<<(ans[i]==inf?-1:ans[i]-1)<<'\n'; // for(int i=1;i<=numQuery;++i) cerr<<(ans[i]==inf?-1:ans[i]-1)<<'\n'; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); // freopen(TASK".inp","r",stdin); // freopen(TASK".out","w",stdout); int testcase=1; // cin>>testcase; while (testcase--) solve(); return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...