題意大致就是有n個人有兩種不同的意見並且有許多朋友,需要讓朋友間盡可能的統一意見(少發生衝突),如果乙個人違反自己的本意也算衝突,求最少的衝突。。。
明眼人直接發現是最小割,兩種意見可以看作源點s和t,我們需要做的是割最少的邊使得s和t成為兩個不同的集合,解釋:割掉的邊相當於1次衝突(因為若某邊被割走,則顯然這條邊相連的兩個點分別通向了s和t,所以算是一次衝突),當s和t還連通時則必然存在一條路徑,這樣肯定會有衝突,所以需要使得s和t孤立。
實現時這樣建圖:直接將s連向同意的人,t連向不同意的人,若兩人是朋友,則在他們之間連一條雙向邊(這裡有些人不理解:若兩個人有衝突,則只需要其中任意乙個人改變意見就行了,簡單說是讓a同意b的意見或者b同意a的意見,所以只需割掉一條邊滿足一種情況就可以了,但是有兩種情況,所以建雙向邊)。最後就是求最小割了,直接套上最大流的模板就ok了。
#include #include #include #include #include using namespace std;
const int maxn = 1000;
const int inf = 0x3f3f3f3;
int n,m;
struct edge;
vectoredges;
vectorg[maxn];
void addedge(int u,int v,int cap));
edges.push_back((edge));
int cnt=edges.size();
g[u].push_back(cnt-2);
g[v].push_back(cnt-1);
}int cur[maxn],vis[maxn],dep[maxn],s,t;
int dfs(int x,int a)
}return flow;
}queueq;
bool bfs()}}
return vis[t];
}int dinic()
return flow;
}int main()
for(int i=1;i<=m;i++)
printf("%d",dinic());
return 0;
}
善意的投票
P2057 SHOI2007 善意的投票
題目描述 幼兒園裡有n個小朋友打算通過投票來決定睡不睡午覺。對他們來說,這個問題並不是很重要,於是他們決定發揚謙讓精神。雖然每個人都有自己的主見,但是為了照顧一下自己朋友的想法,他們也可以投和自己本來意願相反的票。我們定義一次投票的衝突數為好朋友之間發生衝突的總數加上和所有和自己本來意願發生衝突的人...
題解 P2057 SHOI2007 善意的投票
傳送們 幼兒園裡有n個小朋友打算通過投票來決定睡不睡午覺。對他們來說,這個問題並不是很重要,於是他們決定發揚謙讓精神。雖然每個人都有自己的主見,但是為了照顧一下自己朋友的想法,他們也可以投和自己本來意願相反的票。我們定義一次投票的衝突數為好朋友之間發生衝突的總數加上和所有和自己本來意願發生衝突的人數...
洛谷P2057 SHOI2007 善意的投票
題目鏈結 這道題是最小割的乙個經典應用 劃分集合。題目的意思就是就是將所有的小朋友分為兩個集合 同意睡覺和不同意睡覺的。不同的集合之間的邊都要斷開。我們設 s 為投票結果為不想睡覺的小朋友 顏色為0 的集合 t 為投票結果為想睡覺的小朋友 顏色為1 的集合。然後對於乙個小朋友 i 設他的 顏色 為x...