在說這道題之前,讓我們先思考一下最小割的性質.最小割就是使得s到t不同割掉的最小邊的容量,割過之後,所有的點要麼與s聯通,要麼與t聯通.
這樣的性質,即要麼與s有關係,要麼與t有關係的性質(非黑即白)就是典型的最小割的題目.
而這道題就顯然,乙個人要麼選文,要麼選理,沒其他的選擇了.所以我們鎖定最小割.首先我們將文科分到s這邊,理科分到t這邊.
具體做法就是s向x連邊,邊權是選文的滿意度,x向t連邊,邊權是選理的滿意度,由於最小割要使得s->t不連通,所以一定還有一條邊會被割掉..
沒被割掉的就是我們保留的選擇.之後的事情考慮如何將same用上...
我們可以新建一些節點,具體的對於x而言,設y是他的周圍的人,我們考慮same_art的情況,只有x即y都選art時same_art才能被統計答案.
如果有一人選science那same_art就不能統計答案.具體做法我們新建乙個點z,將z向所有的y連inf的邊,表示這條邊不能割斷,再從s向z連一條same_art的邊.這樣,考慮z對最小割的影響.要麼所有的y把理科的邊割掉,則z自然不連通,可以被統計答案.要麼就是講s到z的割掉,即可.
這正好對應我們的條件,第一種情況是全選文,第二種情況是有人選理..
至於same_science的情況,同上類似...
#include#define ll long longview codeusing
namespace
std;
const
int n=110,inf=1e9;
int n,m,link[n*n*3],tot=1,s,t,dx[5]=,dy[5]=;
int d[n*n*3],current[n*n*3
],sum;
struct edgea[n*n*n*30
]; inline
intread()
while(isdigit(ch))
return x*ff;
}inline
void add(int x,int y,int
v)inline
bool
bfs()
}return
false;}
inline
int dinic(int x,int
flow)
}return flow-rest;
}int
main()
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
add(s,(i-1)*m+j+n*m,v);
}
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
add((i-1)*m+j+n*m*2
,t,v);
}
int maxflow=0
,flow;
while
(bfs())
while(flow=dinic(s,inf)) maxflow+=flow;
printf("%d
",sum-maxflow);
return
0;
}
P4313 文理分科 最小割
有n m n mn m個人,第 i,j i,j i,j 選擇文科就可以獲得art i,jart arti,j 的價值,選擇理科就可以獲得sci i,jsci scii,j 的價值。如果乙個選擇文科的人周圍都選擇了文科,那麼就可以多獲得sam e ar ti,j same art same a rti...
P4313 文理分科
遇到這種利益衝突的最終利益最大化問題 考慮轉化為最小割,使得損失的價值最小 相當於文科是s,理科是t,選出最小割就是確定損失代價最小的方案 然後就把s向每個點連一條cap art i j 的邊,每個點向t連一條cap science i j 的邊,再新建n m個點表示同選文科的利益,然後s向每個新建...
BZOJ 3894 文理分科 最小割
題目大意 給定乙個m n的矩陣,每個格仔的人可以學文或者學理,學文和學理各有乙個滿意度,如果以某人為中心的十字內所有人都學文或者學理還會得到乙個額外滿意度,求最大滿意度之和 令s集為學文,t集為學理 每個人學文或者學理的滿意度很好連邊 如果某個集合內的人都學理會獲得乙個滿意度,那麼就新加乙個點,將集...