[Backpack dp] Team group UVA1627

This morning was miraculously stuck by two DPs with a small error. . .

The meaning of the question: Given whether each person knows another person (possibly one-way knowledge), divide into two groups to let the people in each group know each other, minimize the difference between the two groups and output the plan

Connecting each pair of people who do not know each other means that they cannot be divided into a group. In this case, there may be many connected components. However, each connected component does not affect each other, so you can color the bipartite graph separately, and then count How many people are in this connected component for the two colors. In this way, people are divided into k groups. In each group, the people who dyed black can go to Team1 or Team2. There is a difference. For example, there are 2 more people in black than white. If Team1 chooses black, then There are two more than Team2, and vice versa, there will be two less, what is this like? Backpack! However, the value may appear negative and cannot be used as an array subscript, so just add a large number. The bool array dp[i][j] represents whether the i group can get j before the selection

Then I wrote it happily, WA, vjudge didn't give me the data, I didn't know how to write SPJ, I could only make my own data, and it was very sad, and then I finally took it out! Multiple sets of data dp arrays do not have memset... Multiple sets of data are really pits, and the provincial election day2t1 seniors' fancy demonstrations have no line breaks or memsets and other fancy explosions. . .

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
struct Group{
	int N0,N1;
	int val(){
		return abs(N0-N1);
	}
}T[200000];
int n,m1,h[2020],C[2200],N1,N0,pre[2010][2010],A[20020],T1[5020],T2[5020];
bool v[2010][200],dp[2010][2010],flag;
struct edge{
	int next,to;
	void Add(int Next,int To){
		next=Next; to=To;
	}
}q[200200];
void addedge(int x,int y){
	q[++m1].Add(h[x],y); h[x]=m1;
	q[++m1].Add(h[y],x); h[y]=m1;
}
void Dfs(int x,int c){
	int i,y;
	C[x]=c;
	if (c==0) N0++;
	else N1++;
	for (i=h[x];i;i=q[i].next){
		y=q[i].to;
		if (C[y]!=-1){
			if (C[y]!=1-c){
				flag=1;
				return;
			}
			continue;
		}
		Dfs(y,1-c);
		if (flag) return;
	}
}//Bipartite graph coloring
void dfs(int x,int c){
	if (C[x]==c) T1[++T1[0]]=x;
	else T2[++T2[0]]=x;
	C[x]=-1;
	
	int i,y;
	for (i=h[x];i;i=q[i].next){
		y=q[i].to;
		if (C[y]!=-1)
			dfs(y,c);
	}
}
void Work(){
	scanf("%d",&n);
	m1=0; flag=0;
	memset(v,0,sizeof(v));
	memset(h,0,sizeof(h));
	memset(q,0,sizeof(q));
	memset(C,-1,sizeof(C));
	memset(pre,0,sizeof(pre));
	memset(dp,0,sizeof(dp));
	T1[0]=T2[0]=0;
	
	int i,x,j,k=0;
	for (i=1;i<=n;i++){
		while (cin>>x){
			if (!x) break;
			v[i][x]=1;
		}
	}
	for (i=1;i<=n;i++)
		for (j=i+1;j<=n;j++)
			if (!v[i][j]||!v[j][i])
				addedge(i,j);
	for (i=1;i<=n;i++)
		if (C[i]==-1){
			A[++k]=i; N0=N1=0;
			Dfs(i,0);
			if (flag){
				printf("No solution\n"); return;
			}
			T[k].N0=N0; T[k].N1=N1;
		}
	dp[0][500]=1;//Add each subscript to +500 to avoid negative weight subscripts
	for (i=1;i<=k;i++)
		for (j=350;j<=650;j++)
			if (dp[i-1][j]){
				dp[i][j+T[i].val()]=dp[i][j-T[i].val()]=1;
				pre[i][j+T[i].val()]=i,pre[i][j-T[i].val()]=-i;
			}
	for (i=500;i<=1000;i++)
		if (dp[k][i]){//dp[k][i]写成dp[n][i]了
			N0=i; break;
		}
	//Because if you choose a set to get the optimal solution, then the result of choosing its complement is the same, so the result is symmetrical, you can only find it from one side
	for (i=k;i>=1;i--)
		if (pre[i][N0]<0){
			if (T[i].N0>T[i].N1) dfs(A[i],1);
			else dfs(A[i],0);
			N0+=T[i].val();
		}
		else{
			if (T[i].N0>T[i].N1) dfs(A[i],0);
			else dfs(A[i],1);
			N0-=T[i].val();
		}
	for (i=0;i<=T1[0];i++) printf("%d ",T1[i]);
	printf("\n");
	for (i=0;i<=T2[0];i++) printf("%d ",T2[i]);
	printf("\n");
}
int main(){
	int T;
	scanf("%d",&T);
	for (int i=0;i<T;i++){
		if (i) printf("\n");
		Work();
	}
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325935841&siteId=291194637