ZJOI2007 矩陣遊戲

2022-05-05 18:39:07 字數 1428 閱讀 8157

傳送門

這道題就是一道不大容易被看出來的二分圖匹配……(也可能是我太菜了qaq)

首先我們看一下,題目要求我們把對角線上都填滿。我們把每一行和每一列都抽象成乙個點,那麼我們只要讓每一行和每一列都匹配上就可以。

先把每行向源點連邊,每列向匯點連邊,行和列之間,如果g[i][j]是1的話那麼就把第i行和第j列之間連邊。我們想象一下,交換某兩行或者某兩列之後,其實連邊的情況並沒有發生變化,也就是說,最大匹配數無論怎麼交換都不會發生改變。

所以只要在最開始的圖上跑一遍dinic求最大匹配即可,如果其等於n說明可以,否則不行。

#include#include

#include

#include

#include

#define rep(i,a,n) for(int i = a;i <= n;i++)

#define per(i,n,a) for(int i = n;i >= a;i--)

#define enter putchar('\n')

using

namespace

std;

const

int m = 1005

;const

int n = 100005

;const

int inf =1e9;

typedef

long

long

ll;int

read()

while(ch >= '

0' && ch <= '9'

)

return ans *op;

}struct

node

e[n];

int t,n,deep[m],source,sink,a,head[m],cur[m],ecnt = -1

,maxflow;

queue

q;void

clear()

void add(int x,int y,int

z)bool bfs(int s,int

t) }

if(deep[t] == -1) return0;

else

return1;

}int dfs(int s,int t,int

limit)

}if(!flow) deep[s] = -2333333

;

return

flow;

}void dinic(int s,int

t)int

main()

dinic(source,sink);

if(maxflow == n) printf("

yes\n");

else printf("

no\n");

}return0;

}

ZJOI2007 矩陣遊戲

霧。既然我們要求每行每列都要有乙個 1 那麼我們就可以這樣進行建立了這個二分圖。左邊有 n 個點,代表行,右邊有 n 個點,代表列。做這題的主要目的是打板子 二分圖匹配用的dinic bzoj 1059 這裡寫鏈結內容 include include include include include ...

ZJOI2007 矩陣遊戲

我們發現同行同列的點無論經過多少次變換仍然同行或同列,所以題目可轉換為能不能找到n個互相不同行或同列的點。那麼我們用二分圖求一下最大匹配即可。include using namespace std const int n 205 int t,n,x,ans int match n 1 bool vi...

ZJOI2007 矩陣遊戲

這道題是乙個不錯的題,難點就在於建模。交換操作過程中,同一行的黑塊是不會被拆開,同理縱塊也是。接著目標狀態就是一條對角線上全都是黑塊。我們倒過來想,看看能否從目標狀態變成初始狀態。對於所有的黑塊 x,y 左邊行右邊列,點分行列 我們連條邊 x leftarrow rightarrow y 顯然目標狀...