#include <stdio.h>
#define MAX 110
int numOfTasks, numOfPairs;
int numOfProblems;
typedef struct Node{
int to;
int next;
}Node;
//用邻接链表存储题目
//注意数组别开小了,千万别只是开MAX的大小!!!
Node NodeArray[MAX * 2];
int numOfNodes;
int head[MAX];
int problemColor[MAX];
typedef struct Set{
int colorStack[3][MAX];
int colorTop[3];
int colorInRound1;
}Set;
Set SetArray[MAX];
int numOfSets;
int fail;
int divided;
void addPair(int from, int to){
numOfNodes++;
NodeArray[numOfNodes].to = to;
NodeArray[numOfNodes].next = head[from];
head[from] = numOfNodes;
}
void colorPairedProblems(int problem, int SetNum, int color){
problemColor[problem] = color;
int top = ++(SetArray[SetNum].colorTop[color]);
SetArray[SetNum].colorStack[color][top] = problem;
int pairColor = 3 - color;
int i, pairedProblem, pairedProblemColor;
for (i = head[problem]; i != 0; i = NodeArray[i].next){
pairedProblem = NodeArray[i].to;
pairedProblemColor = problemColor[pairedProblem];
if (pairedProblemColor == color){
fail = 1;
return;
}
if (pairedProblemColor == 0)
colorPairedProblems(pairedProblem, SetNum, pairColor);
if (fail)
return;
}
}
void divideIntoRounds(int SetNum, int numOfTasksInRound1, int numOfTaskInBound2){
if (SetNum == numOfSets + 1){
if (numOfTasksInRound1 == numOfTasks)
divided = 1;
return;
}
//必须用通过计算两个round的task的数量来剪枝,可以大大地提高效率(不比用分组背包做差),不然会超时
if (numOfTasksInRound1 > numOfTasks || numOfTaskInBound2 > numOfTasks)
return;
SetArray[SetNum].colorInRound1 = 1;
divideIntoRounds(SetNum + 1, numOfTasksInRound1 + SetArray[SetNum].colorTop[1], numOfTaskInBound2 + SetArray[SetNum].colorTop[2]);
if (divided)
return;
SetArray[SetNum].colorInRound1 = 2;
divideIntoRounds(SetNum + 1, numOfTasksInRound1 + SetArray[SetNum].colorTop[2],numOfTaskInBound2 + SetArray[SetNum].colorTop[1]);
if (divided)
return;
}
int main(){
scanf("%d%d", &numOfTasks, &numOfPairs);
numOfProblems = numOfTasks << 1;
int i, one, another;
for (i = 1; i <= numOfPairs; i++){
scanf("%d%d", &one, &another);
addPair(one, another);
addPair(another, one);
}
for (i = 1; i <= numOfProblems; i++){
if (problemColor[i] == 0){
numOfSets++;
colorPairedProblems(i, numOfSets, 1);
}
if (fail){
printf("IMPOSSIBLE\n");
return 0;
}
}
divideIntoRounds(1, 0, 0);
if (divided == 0){
printf("IMPOSSIBLE\n");
return 0;
}
Set tempSet;
int colorInRound1, top, j;
for (i = 1; i <= numOfSets; i++){
tempSet = SetArray[i];
colorInRound1 = tempSet.colorInRound1;
top = tempSet.colorTop[colorInRound1];
for (j = 1; j <= top; j++)
printf("%d ", tempSet.colorStack[colorInRound1][j]);
}
printf("\n");
int colorInRound2;
for (i = 1; i <= numOfSets; i++){
tempSet = SetArray[i];
colorInRound2 = 3 - tempSet.colorInRound1;
top = tempSet.colorTop[colorInRound2];
for (j = 1; j <= top; j++)
printf("%d ", tempSet.colorStack[colorInRound2][j]);
}
printf("\n");
return 0;
}
URAL 1156 Two Rounds (DFS二分染色 + DFS枚举 + 剪枝)
最新推荐文章于 2015-10-22 22:08:00 发布