文理分科是一件很糾結的事情!(雖然看到這個題目的人肯定都沒有糾
結過)小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 #include2using
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,這個人以...