題目鏈結
這道題是最小割的乙個經典應用:劃分集合。
題目的意思就是就是將所有的小朋友分為兩個集合:同意睡覺和不同意睡覺的。不同的集合之間的邊都要斷開。
我們設\(s\)為投票結果為不想睡覺的小朋友(顏色為0)的集合;\(t\)為投票結果為想睡覺的小朋友(顏色為1)的集合。然後對於乙個小朋友\(i\),設他的「顏色」為x,那麼我們就連兩條邊\((s,i,[x!=0]),(i,t,[x!=1])\)。第一條邊表示該小朋友屬於\(s\)集合,第二條邊表示該小朋友屬於\(t\)集合。
因為投與自己意願相反的票會產生衝突,所以需要給定流量。
然後對於一對好朋友\(i,j\),我們連\((i,j,1)\)的雙向邊。
實際操作中,流量為0的邊自然可以不連。
答案就是最小割。這是因為,如果\(s\)和\(t\)之間還有流量,說明還有至少一對有衝突的好朋友存在。從這個角度來想,那麼答案和最小割等價的。
如果要問最後小朋友們投的是那些票,那就看最小割割的是哪些邊。如果割的是\((i,j)\),表示保留衝突。如果割的是\((s,i)\)或\((i,t)\),表示\(i\)投了意願相反的票。
**:
#include#define ll long long
#define n 305
using namespace std;
inline int get() while('0'<=ch&&ch<='9') return x*f;}
int n,m;
int s,t;
struct load s[n*n<<2];
int h[n],cnt=1;
void add(int i,int j,int flow) ;h[i]=cnt;
s[++cnt]=(load) ;h[j]=cnt;
}int dis[n],gap[n];
int dfs(int v,int maxf)
} if(!(--gap[dis[v]])) dis[s]=n+2;
gap[++dis[v]]++;
return ret;
}int sap()
void init()
int main()
for(int i=1;i<=m;i++)
cout
}
P2057 SHOI2007 善意的投票
題目描述 幼兒園裡有n個小朋友打算通過投票來決定睡不睡午覺。對他們來說,這個問題並不是很重要,於是他們決定發揚謙讓精神。雖然每個人都有自己的主見,但是為了照顧一下自己朋友的想法,他們也可以投和自己本來意願相反的票。我們定義一次投票的衝突數為好朋友之間發生衝突的總數加上和所有和自己本來意願發生衝突的人...
題解 P2057 SHOI2007 善意的投票
傳送們 幼兒園裡有n個小朋友打算通過投票來決定睡不睡午覺。對他們來說,這個問題並不是很重要,於是他們決定發揚謙讓精神。雖然每個人都有自己的主見,但是為了照顧一下自己朋友的想法,他們也可以投和自己本來意願相反的票。我們定義一次投票的衝突數為好朋友之間發生衝突的總數加上和所有和自己本來意願發生衝突的人數...
洛谷 P2007 魔方
常神牛從來沒接觸過魔方,所以他要借助計算機來玩。即使是這樣,他還是很菜。常神牛家的魔方都是3 3 3的三階魔方,大家都見過。更正 3 4以圖為準。作為一名菜鳥,常神牛從網上搜了一篇攻略,並找人翻譯成了他自己會做的方法。現在告訴你他的魔方情況,以及他從網上搜到的攻略,請你求出最後魔方變成什麼樣子。輸入...