日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【LOJ】#2084. 「NOI2016」网格

發(fā)布時間:2024/10/12 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【LOJ】#2084. 「NOI2016」网格 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題解

之前用的mapTLE了,今天用了個hash把題卡了過去,AC數(shù)++

我們只要保留一個點為中心周圍5 * 5個格子就可以

如果一個點周圍5*5個格子有兩個不連通,那么顯然輸出0

如果一個出現(xiàn)了一個割點,那么看看這個割點在不在離中心點的第一層,如果在的話就是1,沒有合法割點的話就是2

然后就是特判了……特判真的挺多的……

代碼

#include <bits/stdc++.h> //#define ivorysi #define MAXN 100005 #define mo 974711 #define INF 1000000000000000000LL #define pii pair<int,int> #define fi first #define se second using namespace std; typedef long long int64; pii poi[MAXN * 26]; vector<int> V[MAXN],st; int N,M,c,cnt,T; struct Hash {struct node {int64 x;int next,c;}E[MAXN * 26];int head[mo + 5],sumE;void clear() {sumE = 0;memset(head,0,sizeof(head));}void add(int64 x,int c) {int u = x % mo;E[++sumE].x = x;E[sumE].next = head[u];E[sumE].c = c;head[u] = sumE;}void Insert(pii x,int c) {add(1LL * (x.fi - 1) * M + x.se,c);}int Query(pii x) {int u = (1LL * (x.fi - 1) * M + x.se) % mo;for(int i = head[u] ; i ; i = E[i].next) {if(E[i].x == 1LL * (x.fi - 1) * M + x.se) return E[i].c;}return -1;} }H; int dx[] = {0,0,1,-1}; int dy[] = {1,-1,0,0}; struct node {int to,next; }edge[MAXN * 100]; int head[MAXN * 26],sumE,low[MAXN * 26],dfn[MAXN * 26],idx,col[MAXN * 26],tot; bool fir[MAXN * 26]; void dfs(int u,int fa) {dfn[u] = low[u] = ++idx;col[u] = tot;int son = 0;for(int i = head[u] ; i ; i = edge[i].next) {int v = edge[i].to;if(v != fa) {if(dfn[v]) low[u] = min(low[u],dfn[v]);else {++son;dfs(v,u);low[u] = min(low[u],low[v]);if(fa != 0 && low[v] >= dfn[u]) {st.push_back(u);}}}}if(!fa && son > 1) st.push_back(u); } void add(int u,int v) {edge[++sumE].to = v;edge[sumE].next = head[u];head[u] = sumE; } void Init() {sumE = 0;for(int i = 1 ; i <= cnt ; ++i) {head[i] = dfn[i] = low[i] = col[i] = fir[i] = tot = idx = 0;}H.clear();int u,v;for(int i = 1 ; i <= c ; ++i) {scanf("%d%d",&u,&v);poi[i] = make_pair(u,v);H.Insert(poi[i],i);}cnt = c;for(int i = 1 ; i <= c ; ++i) {V[i].clear();for(int x = -2 ; x <= 2 ; ++x) {for(int y = -2 ; y <= 2 ; ++y) {if(x == 0 && y == 0) continue;pii tmp = make_pair(poi[i].fi + x,poi[i].se + y);if(tmp.fi < 1 || tmp.fi > N || tmp.se < 1 || tmp.se > M) continue;if(H.Query(tmp) == -1) {poi[++cnt] = tmp;H.Insert(poi[cnt],cnt);}if(x <= 1 && x >= -1 && y <= 1 && y >= -1) fir[H.Query(tmp)] = 1;V[i].push_back(H.Query(tmp));}}}for(int i = c + 1 ; i <= cnt ; ++i) {for(int j = 0 ; j <= 3 ; ++j) {pii tmp = make_pair(poi[i].fi + dx[j],poi[i].se + dy[j]);if(tmp.fi < 1 || tmp.fi > N || tmp.se < 1 || tmp.se > M) continue;int x = H.Query(tmp);if(x <= c) continue;add(i,x);}} } void Solve() {scanf("%d",&T);while(T--) {scanf("%d%d%d",&N,&M,&c);Init();if(1LL * N * M - c <= 1) {puts("-1");goto again;}if(c == 0) {if(1LL * N * M == 2) puts("-1");else if(N == 1 || M == 1) puts("1");else puts("2");goto again;}st.clear();for(int i = c + 1 ; i <= cnt ; ++i) {if(!dfn[i]) {++tot;dfs(i,0);}}for(int i = 1 ; i <= c ; ++i) {int t = 0;for(auto k : V[i]) {if(k <= c) continue;if(k > c) {if(t == 0) t = col[k];else if(t != col[k]) {puts("0");goto again;}}}}if(1LL * N * M - c == 2) {puts("-1");goto again;}for(auto k : st) {if(fir[k]) {puts("1");goto again;}}if(M == 1 || N == 1) puts("1");else puts("2");again:;} }int main() { #ifdef ivorysifreopen("f1.in","r",stdin); #endifSolve(); }

轉(zhuǎn)載于:https://www.cnblogs.com/ivorysi/p/9560087.html

總結(jié)

以上是生活随笔為你收集整理的【LOJ】#2084. 「NOI2016」网格的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。