在一些一對一遊戲的比賽(如下棋、桌球和羽毛球的單打)中,我們經常會遇到a勝過b,b勝過c而c又勝過a的有趣情況,不妨形象的稱之為剪刀石頭布情況。有的時候,無聊的人們會津津樂道於統計有多少這樣的剪刀石頭布情況發生,即有多少對無序三元組(a, b, c),滿足其中的乙個人在比賽中贏了另乙個人,另乙個人贏了第三個人而第三個人又勝過了第乙個人。注意這裡無序的意思是說三元組中元素的順序並不重要,將(a, b, c)、(a, c, b)、(b, a, c)、(b, c, a)、(c, a, b)和(c, b, a)視為相同的情況。
有n個人參加一場這樣的遊戲的比賽,賽程規定任意兩個人之間都要進行一場比賽:這樣總共有場比賽。比賽已經進行了一部分,我們想知道在極端情況下,比賽結束後最多會發生多少剪刀石頭布情況。即給出已經發生的比賽結果,而你可以任意安排剩下的比賽的結果,以得到盡量多的剪刀石頭布情況。
輸入檔案的第1行是乙個整數n,表示參加比賽的人數。
之後是乙個n行n列的數字矩陣:一共n行,每行n列,數字間用空格隔開。
在第(i+1)行的第j列的數字如果是1,則表示i在已經發生的比賽中贏了j;該數字若是0,則表示在已經發生的比賽中i敗於j;該數字是2,表示i和j之間的比賽尚未發生。數字矩陣對角線上的數字,即第(i+1)行第i列的數字都是0,它們僅僅是佔位符號,沒有任何意義。
輸入檔案保證合法,不會發生矛盾,當i≠j時,第(i+1)行第j列和第(j+1)行第i列的兩個數字要麼都是2,要麼乙個是0乙個是1。
輸出檔案的第1行是乙個整數,表示在你安排的比賽結果中,出現了多少剪刀石頭布情況。
輸出檔案的第2行開始有乙個和輸入檔案中格式相同的n行n列的數字矩陣。第(i+1)行第j個數字描述了i和j之間的比賽結果,1表示i贏了j,0表示i負於j,與輸入矩陣不同的是,在這個矩陣中沒有表示比賽尚未進行的數字2;對角線上的數字都是0。輸出矩陣要保證合法,不能發生矛盾。
3
0 1 2
0 0 2
2 2 0
1
0 1 0
0 0 1
1 0 0
神題...
考慮補集轉化,滿足條件的不好求,那就求不滿足條件的。
設第\(i\)個人贏了\(val_i\)次,那麼不滿足條件的三元組個數就是:
\[\sum_^\binom=\sum_^val_i(val_i-1)/2
\]考慮網路流建圖:
那麼這個圖的每種最大流都表示一種可行的方案。
現在我們的目的就是給這個圖加上費用,使得費用最小。
那麼對於點\(a_i\),若流向\(t\)的流量為\(x\),費用就是\(x(x-1)/2\),但是這裡是乙個二次的增長,一般的建圖就做不了了。
可以考慮把這條邊拆成\(n\)條,每條容量為\(1\),費用依次遞增,即費用為\(0,1,2,...,n-1\),那麼可以發現,由於費用流每次增廣都會選擇最小的那條邊,所以流量為\(x\)時費用為\(x(x-1)/2\),即滿足條件。
然後建完圖跑最小費用最大流,然後拿總方案減一下就好了。
輸出方案隨便列舉一下那條邊流滿了就好了。
#includeusing namespace std;
void read(int &x)
void print(int x)
void write(int x)
const int maxn = 2e5+10;
const int inf = 1e9;
int n,s,t,tot=1,cnt,cost;
int head[maxn],vis[maxn],dis[maxn],val[maxn],mp[102][102];
struct edgee[maxn];
void add(int u,int v,int w,int c) ,head[u]=tot;}
void ins(int u,int v,int w,int c)
int bfs()
} return dis[t]0&&dis[e[i].to]==dis[x]+e[i].c)
return used;
}int mcmf()
int tmp[5],top,mark;
int main()
} for(int i=1;i<=n;i++)
for(int j=val[i];j<=n;j++) ins(i,t,1,j);
for(int i=1;i<=n;i++) ans-=val[i]*(val[i]-1)/2;
write(ans-mcmf());
for(int x=n+1;x<=cnt;x++)
mp[tmp[mark]][tmp[mark^1]]=1;
mp[tmp[mark^1]][tmp[mark]]=0;
} for(int i=1;i<=n;i++,puts("")) for(int j=1;j<=n;j++) printf("%d ",mp[i][j]);
return 0;
}
bzoj2597 Wc2007 剪刀石頭布
今天注意力明顯不集中哎 頹 1a 了這道網路流題,思路確實神。題目是給你一張有向圖,讓你新增一些邊使得任意兩個點 a,b 直接都有一條有向邊,可以從a指向b,也可以由b指向a。讓你最大化三元環的數目。according to 姜爺,用補集思想,環不好搞,考慮三個點不成環,那那就是有乙個點連向其它的兩...
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...