文理分科是一件很糾結的事情!(雖然看到這個題目的人肯定都沒有糾
結過)
小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];
接下來n*m個整數,表示same_science[i][j];
n,m<=100,讀入資料均<=500
很經典的模型,題目要求最大收益可以用總的收益-最小割
具體套路就是,每個點分別拆成兩個向源匯點連邊,割掉其中任意一條表示這個點屬於s或t所在的集合
我們規定s所在的集合為文科,並在所有相同點的文理科點間連inf的邊,表示文科邊或理科邊不能被同時割掉
再加入乙個新的點p表示周圍的人都選文科,並和當前點相連的五個點連inf的邊,連源點和p容量為same_art,這樣能保證只有五條邊都割才能取到這權值
需要指出的是,一條連線源匯點的路徑上一定有弧被割,即任意一點一定不屬於s集就屬於t集(大概只有我不知道吧)
#include
#include
#include
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
#define fill(x,t) memset(x,t,sizeof(x))
#define min(x,y) ((x)<(y)?(x):(y))
const
int inf=0x3f3f3f3f;
const
int l=205;
const
int n=50005;
const
int e=1000005;
struct edgee[e];
std:: queue
que;
int cur[n],ls[n],edcnt=1;
int a[l][l],b[l][l],c[l][l],d[l][l],id[l][l];
int dx[4][2]=,,,};
int dis[n];
int read()
void addedge(int x,int y,int w) ; ls[x]=edcnt;
e[++edcnt]=(edge); ls[y]=edcnt;
}int find(int now,int ed,int mn)
}return ret;
}int bfs(int st,int ed) }}
return0;}
int dinic(int st,int ed)
return ret;
}int main(void) }}
ans-=dinic(0,cnt*4+1);
printf("%d\n", ans);
return
0;}
BZOJ 3894 文理分科 最小割
題目大意 給定乙個m n的矩陣,每個格仔的人可以學文或者學理,學文和學理各有乙個滿意度,如果以某人為中心的十字內所有人都學文或者學理還會得到乙個額外滿意度,求最大滿意度之和 令s集為學文,t集為學理 每個人學文或者學理的滿意度很好連邊 如果某個集合內的人都學理會獲得乙個滿意度,那麼就新加乙個點,將集...
BZOJ 3894 文理分科 最小割
題目大意 給出乙個 每個人要選擇文科或者理科,每個人選擇文科有乙個滿意度,選擇理科有乙個滿意度,以乙個人為中心的五個人全選擇一科也有乙個滿意度。問最大的滿意度是多少。思路 以後看到文理分科之類的8成應該就是最小割了。先把答案全部累加起來,然後減去建圖之後的最大流就是答案。s 每個人 f 這個人選擇文...
bzoj 3894 文理分科 最小割
文理分科是一件很糾結的事情!雖然看到這個題目的人肯定都沒有糾 結過 小p所在的班級要進行文理分科。他的班級可以用乙個n m的矩陣進行 描述,每個格仔代表乙個同學的座位。每位同學必須從文科和理科中選擇 一科。同學們在選擇科目的時候會獲得乙個滿意值。滿意值按如下的方式 得到 1 如果第i行第秒j的同學選...