BZOJ3894 文理分科

2022-05-09 00:54:09 字數 3200 閱讀 6758

文理分科是一件很糾結的事情!(雖然看到這個題目的人肯定都沒有糾

結過)小p所在的班級要進行文理分科。他的班級可以用乙個n*m的矩陣進行

描述,每個格仔代表乙個同學的座位。每位同學必須從文科和理科中選擇

一科。同學們在選擇科目的時候會獲得乙個滿意值。滿意值按如下的方式

得到:1.如果第i行第秒j的同學選擇了文科,則他將獲得art[i][j]的滿意值,如

果選擇理科,將得到science[i][j]的滿意值。

2.如果第i行第j列的同學選擇了文科,並且他相鄰(兩個格仔相鄰當且

僅當它們擁有一條相同的邊)的同學全部選擇了文科,則他會更開

心,所以會增加same_art[i][j]的滿意值。

3.如果第i行第j列的同學選擇了理科,並且他相鄰的同學全部選擇了理

科,則增加same_science[i]j的滿意值。

小p想知道,大家應該如何選擇,才能使所有人的滿意值之和最大。請

告訴他這個最大值。

第一行為兩個正整數:n,m

接下來n術m個整數,表示art[i][j];

接下來n術m個整數.表示science[i][j];

接下來n術m個整數,表示same_art[i][j];

輸出為乙個整數,表示最大的滿意值之和

3 413 2 4 13

7 13 8 12

18 17 0 5

8 13 15 4

11 3 8 11

11 18 6 5

1 2 3 4

4 2 3 2

3 1 0 4

3 2 3 2

0 2 2 1

0 2 4 4

152樣例說明

1表示選擇文科,0表示選擇理科,方案如下:

1  0  0  1

0  1  0  0

1  0  0  0

n,m<=100,讀入資料均<=500

感覺題目描述有點問題

不看題解根本不知道怎麼建圖。

分析:首先如果沒有相鄰全選情況,建圖比較容易。文科與s相連,理科與t相連,求最小割,每條路徑必定割掉一條邊。

下面考慮相鄰全選情況。相鄰中有任意一人選文,就沒有額外的理科加成。同理相鄰任意一人選理,就沒有額外的文科加成。根據這個可以這樣建圖,每個點再拆為p1,p2,如圖:

1,2,3,4為某個位置的相鄰點。與p1相連,流量為inf,這樣如果任意乙個選文科(假設a[1]),即與s相連,必定會割掉same_s這條邊。因為選a[1],肯定沒有s[1],要保持不連通,最小割肯定割same_s,不會割inf。同理對於same_a,也一樣。任意乙個選理科(假設s[3]),與t相連,肯定沒有a[3],要保持不連通,最小割肯定割same_a,不會割inf。

這樣建圖滿足了額外加成的控制。

直接用總的滿意度-最小割即可

第一次知道拆點方法,p(i,j) = (i-1)*m+j,然後p1=p(i,j)+n*m  p2=p(i,j)+2*n*m

1 #include2

using

namespace

std;

3#define p(i,j) (i-1)*m+j45

const

int maxn=100010;6

const

int maxm=400010;7

const

int inf=0x3f3f3f3f;8

struct

edgeedge[maxm];

1112

inttol;

13int

head[maxn];

14int

gap[maxn],dep[maxn],cur[maxn];

15int dir[2]=;

16void

init()

20void addedge(int u,int v,int w,int rw=0

) 26

27int

q[maxn];

28void bfs(int start,int

end) 44}

45}4647

ints[maxn];

48int sap(int start,int end,int

n) 63}64

for(int i=0;i)

68 ans+=minn;

69 top=inser;

70 u=edge[s[top]^1

].to;

71continue;72

}73bool flag=false;74

intv;

75for(int i=cur[u];i!=-1;i=edge[i].next) 82}

83if

(flag)

88int minn=n;

89for(int i=head[u];i!=-1;i=edge[i].next) 94}

95 gap[dep[u]]--;

96if(!gap[dep[u]]) return

ans;

97 dep[u]=minn+1

;98 gap[dep[u]]++;

99if(u!=start) u=edge[s[--top]^1

].to;

100}

101return

ans;

102}

103104

intmain()

116}

117for(int i=1;i<=n;i++)

123}

124for(int i=1;i<=n;i++)

134 addedge(s,p(i,j)+2*n*m,x);

135}

136}

137for(int i=1;i<=n;i++)

147 addedge(p(i,j)+n*m,t,x);

148}

149}

150 printf("

%d\n

",sum-sap(0,t,t+1

));151

}152 }

BZOJ 3894 文理分科

time limit 10 sec memory limit 512 mb submit 194 solved 122 submit status discuss description 文理分科是一件很糾結的事情!雖然看到這個題目的人肯定都沒有糾 結過 小p所在的班級要進行文理分科。他的班級可以用...

BZOJ 3894 文理分科

解四個方程。為了簡潔我們畫出來兩個來解方程推理一下。s a aa s b ab a t ba b t bb s x a和其他相關格仔收益 x t 同上 include include include include include define maxn 1000010 using namespac...

bzoj3894 文理分科

s向每個人連邊,容量是選文科的滿意值 每個點向t連邊,容量是選理科的滿意值。再新建2 n m個點,表示每個人和相鄰的人都選文 p1 或都選理 p2 s向p1連邊,容量為這個人的same art,p1再向這個人和相鄰的四個人都連inf的邊 p2向t連邊,容量為這個人的same science,這個人以...