URAL 1156 Two Rounds (DFS二分染色 + 分组背包)

来源:互联网 发布:css和js区别 编辑:程序博客网 时间:2024/06/06 10:07
#include <stdio.h>#define MAX 110int 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 stack[MAX];int top;int colorSize[3];}Set;Set SetArray[MAX];int numOfSets;int fail;int mark[MAX][MAX];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].top);SetArray[SetNum].stack[top] = problem;SetArray[SetNum].colorSize[color]++;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;}}int main(){//freopen("input1.txt", "r", stdin);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;}}mark[0][0] = 1;int set, tasks, tempTasks;for (set = 1; set <= numOfSets; set++)for (tasks = 0; tasks <= numOfTasks; tasks++){if (mark[set - 1][tasks] != 0){tempTasks = tasks + SetArray[set].colorSize[1];if (tempTasks <= numOfTasks && mark[set][tempTasks] == 0)mark[set][tempTasks] = 1;tempTasks = tasks + SetArray[set].colorSize[2];if (tempTasks <= numOfTasks && mark[set][tempTasks] == 0)mark[set][tempTasks] = 2;}}if (mark[numOfSets][numOfTasks] == 0){printf("IMPOSSIBLE\n");return 0;}int numOfTaskLeft = numOfTasks;int top, tempProblem, j;for (set = numOfSets; set > 0; set--){if (mark[set][numOfTaskLeft] == 2){top = SetArray[set].top;//把集合set的所有问题problem的颜色取反for (j = 1; j <= top; j++){tempProblem = SetArray[set].stack[j];problemColor[tempProblem] = 3 - problemColor[tempProblem];}numOfTaskLeft -= SetArray[set].colorSize[2];}elsenumOfTaskLeft -= SetArray[set].colorSize[1];}for (i = 1; i <= numOfProblems; i++)if (problemColor[i] == 1)printf("%d ", i);printf("\n");for (i = 1; i <= numOfProblems; i++)if (problemColor[i] == 2)printf("%d ", i);printf("\n");return 0;}

0 0
原创粉丝点击