今天注意力明顯不集中哎….頹… 1a
了這道網路流題,思路確實神。
題目是給你一張有向圖,讓你新增一些邊使得任意兩個點(a,b)直接都有一條有向邊,可以從a指向b,也可以由b指向a。
讓你最大化三元環的數目。
according to 姜爺,用補集思想,環不好搞,考慮三個點不成環,那那就是有乙個點連向其它的兩個點,那兩個點怎麼連無所謂。那就是說,如果乙個點的出度是cd
i ,就能找到c2
cdi 這麼多三元組不構成三元環。那麼總共不構成三元環的三元組的數目就是∑n
i=1c
di(c
di−1
)2,答案就是an
s=c3
n−∑i
=1nc
di(c
di−1
)2你要最大化an
s ,就是最小化∑n
i=1c
di(c
di−1
)2。 然後就可以開始網路流了,每場比賽建乙個點ci
j 表示i 和
j兩個點打比賽,顯然s→
cij 容量=
1 ,邊權=0
,cij
→i 、c
ij→j
容量1,邊權
0,最後每個點→t
,n條邊,容量都是
1,邊權是0,
1,2,
3,..
.(n−
1)這樣的話,流等於幾就對應這個點的出度是幾,費用流肯定會按邊權從小到**擇,正好對應cd
i(cd
i−1)
2 。
神奇吧?
//費用流
#include
#include
#include
#define maxn 1000000
#define inf 0x3f3f3f3f
using
namespace
std;
int n, head[maxn], to[maxn], nex[maxn], dist[maxn], pre[maxn], c[maxn], w[maxn], tot=1,
s, t, in[maxn], cost, table[maxn], ans[101][101];
queue
q;void adde(int a, int b, int cc, int ww)
void adde2(int a, int b, int cc, int ww)
bool spfa()
}return dist[t]!=inf;
}void augment()
int c(int a, int b)
void build()
for(j=1;j<=n;j++)adde2(i,t,1,j-1);
}}void show()
for(i=1;i<=n;i++)
}int main()
bzoj2597 Wc2007 剪刀石頭布
直接求不好求引入未知數,考慮採用補集轉化 對於一次非剪刀石頭布的情況,定是乙個人贏了另兩個人 若知道乙個人共贏了多少人,那麼就貢獻了n n 1 2種不同的情況 更一般的,乙個人如果多贏了乙個人,他的新增的貢獻就是他當前沒有加上這個人時已經贏了的人 費用流。st 比賽 人 ed,費用是遞增的,對於人拆...
bzoj2597 Wc2007 剪刀石頭布
time limit 20 sec memory limit 128 mbsec special judge submit 1765 solved 763 submit status discuss 在一些一對一遊戲的比賽 如下棋 桌球和羽毛球的單打 中,我們經常會遇到a勝過b,b勝過c而c又勝過a...
BZOJ2597 WC2007 剪刀石頭布
在一些一對一遊戲的比賽 如下棋 桌球和羽毛球的單打 中,我們經常會遇到a勝過b,b勝過c而c又勝過a的有趣情況,不妨形象的稱之為剪刀石頭布情況。有的時候,無聊的人們會津津樂道於統計有多少這樣的剪刀石頭布情況發生,即有多少對無序三元組 a,b,c 滿足其中的乙個人在比賽中贏了另乙個人,另乙個人贏了第三...