【题目大意】:给出n个士兵和m组关系,每个士兵均被划分在Blue组或者是Red组,m组关系描述的是士兵x,y直接是否是亲密关系。由于具备亲密关系的两个士兵被分在两个不同的组,那么对训练结果会产生不好的影响,问你最少去掉多少个士兵能够避免掉这种影响。并输出字典序最小的方案。
【解题思路】:题目一看下来,第一感觉就是写个二分图的最大匹配,所以一开始加了个源点和汇点就敲了个网络流。最大匹配是搞定了~问题是方案不会搞,所以yy了一下~想想自己没写过匈牙利算法就试一下吧,顺便学学。匈牙利算法是利用dfs寻找增广路径来确定最大匹配的。因为题目要求的是字典序最小,因此我们不妨从0~n-1进行枚举,删除该点后对新的图跑一次匈牙利算法,得到的新的增广路,观察新的增广路径是否变小,若变小则说明此点必在答案中。
【匈牙利算法】:摘自网络:
匈牙利算法是基于Hall定理中充分性证明的思想,它是部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最大匹配的算法。
假设:M是G的一个匹配。
M-交错路:p是G的一条通路,如果p中的边为属于M中的边与不属于M但属于G中的边交替出现,则称p是一条M-交错路。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
#define maxn 300
#define maxm 21000
struct edge{
int u,v;
int next;
};
int eh[maxn],tot,ans;
int T,n,m;
edge et[maxm];
bool visit[maxn];
int match[maxn];
int po[maxn];
void addd(int u,int v){
edge E = {u,v,eh[u]};
et[tot] = E, eh[u] = tot++;
}
void addedge(int u,int v){
addd(u,v);
}
bool dfs(int u) {
for (int i = eh[u]; i != -1; i = et[i].next){
if (!visit[et[i].v] && po[et[i].v]==1){
visit[et[i].v]=true;
if (match[et[i].v] == -1 || dfs(match[et[i].v])) {
match[et[i].v] = u;
return true;
}
}
}
return false;
}
int Match() {
int cnt = 0;
memset(match, -1, sizeof (match));
for (int u = 0; u < n; u++) {
memset(visit, false, sizeof (visit));
if (!po[u] && dfs(u)) cnt++;
}
return cnt;
}
void solve(){
int anss[maxn];
int cnt=0;
for(int i=0; i<n; i++){
po[i]=po[i]^1;
int tmp=Match();
if(tmp<ans){
ans=tmp;
anss[cnt++]=i;
}
else{
po[i]=po[i]^1;
}
}
printf("%d",cnt);
for(int i=0;i<cnt;i++){
printf(" %d",anss[i]);
}
printf("\n");
}
int main(){
scanf("%d", &T);
while (T--){
scanf("%d%d",&n,&m);
int tmp;
for (int i=0; i<n; i++){
scanf("%d",&tmp);
po[i]=tmp;
}
int x,y;
tot=0;
memset(eh,-1,sizeof(eh));
for (int i=0; i<m; i++){
scanf("%d%d",&x,&y);
if (po[x]!=po[y]){
if (po[x]==0) addedge(x,y);
else addedge(y,x);
}
}
ans=Match();
solve();
}
}
本文探讨如何通过最少的士兵调整,确保不同亲密关系的士兵分在不同组内,以最小化对训练结果的负面影响。通过二分图匹配与匈牙利算法,实现最优解并输出字典序最小的方案。
&spm=1001.2101.3001.5002&articleId=7310671&d=1&t=3&u=6a71a197b8d6471d83c4069450d1c5a1)

被折叠的 条评论
为什么被折叠?



