time limit: 40 sec
memory limit: 128 mb
submit: 3052
solved: 840 [
submit][
status][
discuss]
blinker最近喜歡上乙個奇怪的遊戲。
這個遊戲在乙個 n*m 的棋盤上玩,每個格仔有乙個數。每次 blinker 會選擇兩個相鄰
的格仔,並使這兩個數都加上 1。
現在 blinker 想知道最少多少次能使棋盤上的數都變成同乙個數,如果永遠不能變成同
乙個數則輸出-1。
輸入的第一行是乙個整數t,表示輸入資料有t輪遊戲組成。
每輪遊戲的第一行有兩個整數n和m, 分別代表棋盤的行數和列數。
接下來有n行,每行 m個數。
對於每個遊戲輸出最少能使遊戲結束的次數,如果永遠不能變成同乙個數則輸出-1。 2
2 2
1 2
2 3
3 3
1 2 3
2 3 4
4 3 2
2 -1
【資料範圍】
對於30%的資料,保證 t<=10,1<=n,m<=8
對於100%的資料,保證 t<=10,1<=n,m<=40,所有數為正整數且小於1000000000 [
submit][
status][
discuss]
如果這個矩形一共有偶數個格仔,那麼顯然可以二分答案
因為你總能找到一些方法把每個格仔的數字累加上去
判斷的話很容易想到用網路流
先把這個矩形二分圖染色
記當前二分now為每個格仔最後的狀態
源點到每個黑點連容量為now - w[i][j]的邊
每個白點到匯點連容量為now - w[i][j]的邊
黑點與白點之間再連邊模擬增加操作
跑一遍最大流
但是奇數的話就沒辦法二分了
列出幾個等式
不妨假設最後每個格仔的元素都是k
記初始時黑點權值和為sx,白點為sy,設黑點tx個,白點ty個
假設一共做了tot次增加操作
由於每個增加操作一定是乙個黑點+1並且乙個白點+1,那麼
sx*tx + tot = k*tx
sy*ty + tot = k*ty
聯立這兩個式子消去tot,發現k的值唯一確定
再判斷一下就好
#include#include#include#include#include#include#include#include#include#include#include#includeusing namespace std;
const int maxn = 1e5 + 10;
typedef long long ll;
const ll inf = 1e15;
const int dx[4] = ;
const int dy[4] = ;
struct e
e(int to,ll cap,ll flow): to(to),cap(cap),flow(flow) {}
}edgs[maxn];
int t,tot,cnt,s,t,n,m,max,cnt,a[55][55],co[55][55]
,vis[maxn],w[55][55],l[maxn],cur[maxn];
ll goal,sum[2],p[2];
vector v[maxn];
queue q;
void color()
t = ++tot;
sum[0] = w[1][1]; p[0] = 1;
sum[1] = p[1] = 0;
co[1][1] = 0;
for (int i = 2; i <= m; i++)
for (int i = 2; i <= n; i++)
for (int i = 2; i <= n; i++)
for (int j = 2; j <= m; j++)
}void add(int x,int y,ll cap)
bool bfs()
} return vis[t] == cnt;
}ll dicnic(int x,ll a)
if (!flow) l[x] = -1;
return flow;
}void clear()
void build(ll now,ll &g0,ll &g1)
g0 += cap;
}else add(a[i][j],t,cap),g1 += cap;
} }bool judge(ll now)
ll maxflow = 0;
while (bfs())
clear();
goal = g1;
return g1 == maxflow;
}void solve1()
if (judge(l)) printf("%lld\n",goal);
else if (judge(r)) printf("%lld\n",goal);
else puts("-1");
}void solve2()
}int main()
return 0;
}
bzoj2756 SCOI2012 奇怪的遊戲
description blinker最近喜歡上乙個奇怪的遊戲。這個遊戲在乙個 n m 的棋盤上玩,每個格仔有乙個數。每次 blinker 會選擇兩個相鄰 的格仔,並使這兩個數都加上 1。現在 blinker 想知道最少多少次能使棋盤上的數都變成同乙個數,如果永遠不能變成同 乙個數則輸出 1。inp...
bzoj2756 SCOI2012 奇怪的遊戲
description blinker最近喜歡上乙個奇怪的遊戲。這個遊戲在乙個 n m 的棋盤上玩,每個格仔有乙個數。每次 blinker 會選擇兩個相鄰的格仔,並使這兩個數都加上 1。現在 blinker 想知道最少多少次能使棋盤上的數都變成同乙個數,如果永遠不能變成同乙個數則輸出 1。input...
bzoj2756 SCOI2012 奇怪的遊戲
blinker最近喜歡上乙個奇怪的遊戲。這個遊戲在乙個 n m 的棋盤上玩,每個格仔有乙個數。每次 blinker 會選擇兩個相鄰的格仔,並使這兩個數都加上 1。現在 blinker 想知道最少多少次能使棋盤上的數都變成同乙個數,如果永遠不能變成同乙個數則輸出 1。輸入的第一行是乙個整數t,表示輸入...