BZOJ2563: 阿貍和桃子的遊戲 貪心
阿新 • • 發佈:2018-10-05
href main data 規模 這樣的 using 自己的 clas 圖片
1. 阿貍和桃子輪流將圖中的頂點染色,阿貍會將頂點染成紅色,桃子會將頂點染成粉色。已經被染過色的點不能再染了,而且每一輪都必須給一個且僅一個頂點染色。
2. 為了保證公平性,節點的個數N為偶數。
3. 經過N/2輪遊戲之後,兩人都得到了一個頂點集合。對於頂點集合S,得分計算方式為
。
由於阿貍石頭剪子布輸給了桃子,所以桃子先染色。兩人都想要使自己的分數比對方多,且多得越多越好。如果兩人都是采用最優策略的,求最終桃子的分數減去阿貍的分數。
6
4
-1
-2
1 2 1
2 3 6
3 4 3
1 4 5
數據規模和約定
對於40%的數據,1 ≤ N ≤ 16。
對於100%的數據,1 ≤ N ≤ 10000,1 ≤ M ≤ 100000,-10000 ≤ w , c ≤ 10000。
Description
阿貍和桃子正在玩一個遊戲,遊戲是在一個帶權圖G=(V, E)上進行的,設節點權值為w(v),邊權為c(e)。遊戲規則是這樣的:1. 阿貍和桃子輪流將圖中的頂點染色,阿貍會將頂點染成紅色,桃子會將頂點染成粉色。已經被染過色的點不能再染了,而且每一輪都必須給一個且僅一個頂點染色。
2. 為了保證公平性,節點的個數N為偶數。
3. 經過N/2輪遊戲之後,兩人都得到了一個頂點集合。對於頂點集合S,得分計算方式為
。
由於阿貍石頭剪子布輸給了桃子,所以桃子先染色。兩人都想要使自己的分數比對方多,且多得越多越好。如果兩人都是采用最優策略的,求最終桃子的分數減去阿貍的分數。
Input
輸入第一行包含兩個正整數N和M,分別表示圖G的節點數和邊數,保證N一定是偶數。
接下來N+M行。
前N行,每行一個整數w,其中第k行為節點k的權值。
後M行,每行三個用空格隔開的整數a b c,表示一條連接節點a和節點b的邊,權值為c。
Output
輸出僅包含一個整數,為桃子的得分減去阿貍的得分。
Sample Input
4 46
4
-1
-2
1 2 1
2 3 6
3 4 3
1 4 5
Sample Output
3數據規模和約定
對於40%的數據,1 ≤ N ≤ 16。
對於100%的數據,1 ≤ N ≤ 10000,1 ≤ M ≤ 100000,-10000 ≤ w , c ≤ 10000。
Solution
這題考轉化啊
參考的這一篇博客,一開始點權不會處理
考慮點和邊的貢獻
(我們以桃子的角度來看)
一個點被選的貢獻是w
不選的貢獻是-w
一條邊如果兩個端點都不選,對答案的貢獻是-c
如果兩個端點中只選擇一個,對答案的貢獻是0
如果兩個端點都選,對答案的貢獻是c
所以我們可以轉化一下,全部在答案裏面先減掉
就可以變成
一個點如果不選,本身對答案的貢獻是0
一個點如果選,本身對答案的貢獻是2*w
一條邊如果兩個端點都不選,對答案的貢獻是0
如果兩個端點中只選擇一個,對答案的貢獻是c
如果兩個端點都選,對答案的貢獻是2*c
那就把點權魔改一下,改成本身的權*2+所有與它相連的邊的邊權
然後就貪心取了
#include <bits/stdc++.h> using namespace std ; #define N 100010 #define ll long long int n , m ; int c[ N ] ; ll ans = 0 ; int main() { scanf( "%d%d" , &n , &m ) ; for( int i = 1 ; i <=n ; i ++ ) { scanf( "%d" , &c[ i ] ) ; ans -= c[ i ] ; c[ i ] *= 2 ; } for( int i = 1 ; i <= m ; i ++ ) { int x , y , z ; scanf( "%d%d%d" , &x , &y , &z ) ; c[ x ] += z ; c[ y ] += z ; ans -= z ; } sort( c + 1 , c + n + 1 ) ; for( int i = n ; i ; i -= 2 ) { ans += c[ i ] ; } printf( "%lld\n" , ans ) ; return 0 ; }
BZOJ2563: 阿貍和桃子的遊戲 貪心