algorithm bicoloring - andstudy/forge GitHub Wiki
-
Vertex ๋ NONE, BLUE, RED 3๊ฐ์ง ์ํ๋ฅผ ๊ฐ์ง
-
Edge ๋ 2๊ฐ์ Vertex index ๋ก ์ด๋ฃจ์ด์ง
- ๋ฐ๋ก ํด๋์ค๋ก ๋ง๋ค์ง๋ ์์์
-
!ProcessEdge() ์์ 2๊ฐ์ Vertex ์์ ๋ค๋ฅด๊ฒ ๋ง๋ ๋ค
-
์จ๊ฒจ์ง ์ ์ฝ์ฌํญ - Edge ์ฒ๋ฆฌ ์์๋ฅผ ์ง์ผ์ผ ํ๋ค
- ๋ฎ์ ๋ฒํธ์ Vertex ๋ถํฐ ์ฒ๋ฆฌ ํด์ผํจ
-
๋ฆฌํฉํ ๋ง์ ์ฌ์ง๊ฐ ๋ ์์ผ๋ ๊ท์ฐฎ์์...
Public Class Bicoloring
Private _vertexes As List(Of Vertex) = New List(Of Vertex)
Private _edges As List(Of List(Of Integer)) = New List(Of List(Of Integer))
Function GetVertex(ByVal index As Integer) As Vertex
Return _vertexes(index)
End Function
Sub SetupEdges(ByVal inputs As List(Of String))
_edges.Clear()
Dim separator() As Char = {" "c}
Dim edgeCount = Integer.Parse(inputs(1))
For i As Integer = 1 To edgeCount
Dim input() As String = inputs(i + 1).Split(separator, StringSplitOptions.RemoveEmptyEntries)
Dim first As Integer = Integer.Parse(input(0))
Dim second As Integer = Integer.Parse(input(1))
Dim edge As List(Of Integer) = New List(Of Integer)
edge.Add(Math.Min(first, second))
edge.Add(Math.Max(first, second))
_edges.Add(edge)
Next
End Sub
Function IsBicolorable(ByVal inputs As List(Of String)) As Boolean
Dim vertexCount As Integer = Integer.Parse(inputs(0))
SetupVertexes(vertexCount)
SetupEdges(inputs)
ProcessAllEdges(_edges)
Dim result As Boolean = IsBicolor(_edges)
Return result
End Function
Function IsBicolor(ByVal edges As List(Of List(Of Integer))) As Boolean
For Each edge As List(Of Integer) In edges
Dim first As Vertex = GetVertex(edge(0))
Dim second As Vertex = GetVertex(edge(1))
If first.Color = second.Color Then
Return False
ElseIf first.Color = COLOR.NONE Or second.Color = COLOR.NONE Then
Return False
End If
Next
Return True
End Function
Sub ProcessAllEdges(ByVal edges As List(Of List(Of Integer)))
For i As Integer = 0 To _edges.Count - 1
For Each edge As List(Of Integer) In edges
If edge(0) = i Then
ProcessEdge(GetVertex(edge(0)), GetVertex(edge(1)))
End If
Next
Next
End Sub
Sub SetupVertexes(ByVal count As Integer)
_vertexes.Clear()
For i As Integer = 1 To count
_vertexes.Add(New Vertex)
Next
End Sub
Function GetVertexCount() As Integer
Return _vertexes.Count
End Function
Sub ProcessEdge(ByVal first As Vertex, ByVal second As Vertex)
If first.Color = COLOR.RED And second.Color = COLOR.NONE Then
second.SetColor(COLOR.BLUE)
ElseIf first.Color = COLOR.BLUE And second.Color = COLOR.NONE Then
second.SetColor(COLOR.RED)
ElseIf first.Color = COLOR.NONE And second.Color = COLOR.RED Then
first.SetColor(COLOR.BLUE)
ElseIf first.Color = COLOR.NONE And second.Color = COLOR.BLUE Then
first.SetColor(COLOR.RED)
ElseIf first.Color = COLOR.NONE And second.Color = COLOR.NONE Then
first.SetColor(COLOR.BLUE)
second.SetColor(COLOR.RED)
End If
End Sub
End Class
Public Enum COLOR
NONE
BLUE
RED
End Enum
Public Class Vertex
Private _color As COLOR = Basic.COLOR.NONE
ReadOnly Property Color()
Get
Return _color
End Get
End Property
Sub SetColor(ByVal aColor As COLOR)
_color = aColor
End Sub
End Class
<TestClass()> _
Public Class BicoloringTest
Private _bicolor As Bicoloring = New Bicoloring
Private _inputs1 As List(Of String) = New List(Of String)
Private _inputs2 As List(Of String) = New List(Of String)
Private _inputs3 As List(Of String) = New List(Of String)
Public Sub New()
_inputs1.Add("3")
_inputs1.Add("3")
_inputs1.Add("0 1")
_inputs1.Add("1 2")
_inputs1.Add("2 0")
_inputs2.Add("9")
_inputs2.Add("8")
_inputs2.Add("0 1")
_inputs2.Add("0 2")
_inputs2.Add("0 3")
_inputs2.Add("0 4")
_inputs2.Add("0 5")
_inputs2.Add("0 6")
_inputs2.Add("0 7")
_inputs2.Add("0 8")
_inputs3.Add("4")
_inputs3.Add("3")
_inputs3.Add("0 2")
_inputs3.Add("2 1")
_inputs3.Add("3 0")
End Sub
<TestMethod()> _
Public Sub SetVertexCountTest()
_bicolor.SetupVertexes(3)
Assert.AreEqual(3, _bicolor.GetVertexCount())
_bicolor.SetupVertexes(9)
Assert.AreEqual(9, _bicolor.GetVertexCount())
End Sub
<TestMethod()> _
Public Sub ProcessEdgeTest()
_bicolor.SetupVertexes(2)
Dim first As Vertex = _bicolor.GetVertex(0)
Dim second As Vertex = _bicolor.GetVertex(1)
second.SetColor(COLOR.BLUE)
_bicolor.ProcessEdge(first, second)
Assert.AreEqual(COLOR.RED, first.Color)
End Sub
<TestMethod()> _
Public Sub IsBicolorableTest()
Assert.IsFalse(_bicolor.IsBicolorable(_inputs1))
Assert.IsTrue(_bicolor.IsBicolorable(_inputs2))
Assert.IsTrue(_bicolor.IsBicolorable(_inputs3))
End Sub
End Class
- 2๊ฐ์ง ์์ผ๋ก ๋ ธ๋๋ฅผ ์น ํ ์ ์๋๋ฐ ์ธ์ ํ ๋ ธ๋๊ฐ์๋ ๋ฐ๋์ ๋ค๋ฅธ ์๊น์ ๊ฐ์ ธ์ผ ํ๋ค.
- 2๊ฐ์ง ์์ผ๋ก ๋ชจ๋ ๋ ธ๋๋ฅผ ์น ํ ์ ์๋๊ฐ?
- ๊ฒ์ , ํฐ์ ๋๊ฐ์ง ์์ด๋ผ๊ณ ํ์ ๋
- ์ฒซ ๋ ธ๋๋ฅผ ๊ฒ์ ์ผ๋ก ์น ํ๊ณ ์ธ์ ๋ ธ๋๋ฅผ ํ๋์ฉ ์น ํด๊ฐ.
- ์ฒซ ๋ ธ๋๋ฅผ ํฐ์์ผ๋ก ์น ํ๊ณ ์ธ์ ๋ ธ๋๋ฅผ ํ๋์ฉ ์น ํด๊ฐ.
- ์ ๋ ๊ฐ์ง๋ฅผ ์๋ํ๊ณ ํ๋๋ผ๋ ๋๋ฉด Bicoloring ๊ฐ๋ฅ
์ ์ฒ ์์ ใฑใฑ
-
์๊ฐ๋ณด๋ค ์๊ฐ์ด ๊ฑธ๋ฆฌ๋๊ตฐ์. :(
/* @JUDGE_ID:parkpd 110401 Cpp "test" */ /* @BEGIN_OF_SOURCE_CODE */ #include <iostream> #include <vector> #include <set> #include <string> #include <strstream> #include <algorithm> #include <map> //#define _UNIT_TEST using namespace std; namespace ATUtil { bool IsInRange(int value, int from, int to) { return (from <= value) && (value <= to); } int ConvertToIndex(char c) { if ('a' <= c && c <= 'z') { return c - 'a'; } else { return -1; } } char ConvertToChar(int i) { return (char)i + 'a'; } typedef map<int, int> IntDB; typedef vector<int> Ints; }; using namespace ATUtil; #ifdef _UNIT_TEST #include "../UnitTest++/src/UnitTest++.h" int main() { UnitTest::RunAllTests(); char temp; cin >> temp; return 0; } #endif // code implement namespace ATCode { /////////////////////////////////////////////////////////////// // CBicoloring class CBicoloring { public: enum { MAX_SIZE = 200 }; enum Color { EMPTY = 0, RED = 1, BLUE = 2, INVALID }; CBicoloring(); void SetVerticesNum(int num); void Connect(int from, int to); bool IsBicolorable(); bool _IsBicolorable(int from); int GetAdjectiveVertex(int from, Ints& ints); string Result(); struct Vertex { Vertex(int index) : m_Index(index), m_Color(EMPTY) {} Color GetOppositeColor() { if (m_Color == RED) { return BLUE; } else if (m_Color == BLUE) { return RED; } else { //_ASSERT(0); return INVALID; } } int m_Index; Color m_Color; }; std::vector<Vertex> m_Vertex; int m_nVertexNum; bool m_GraphEdges[MAX_SIZE][MAX_SIZE]; }; CBicoloring::CBicoloring() : m_nVertexNum(0) { for (int i = 0; i < MAX_SIZE; ++i) { for (int j = 0; j < MAX_SIZE; ++j) { m_GraphEdges[i][j] = false; } } } void CBicoloring::SetVerticesNum(int num) { m_Vertex.reserve(num); for (int i = 0; i < num; ++i) { m_Vertex.push_back(Vertex(i)); } m_nVertexNum = num; } void CBicoloring::Connect(int from, int to) { m_GraphEdges[from][to] = true; m_GraphEdges[to][from] = true; } bool CBicoloring::IsBicolorable() { // ์ ์ฒด vertex ๋ฅผ ์ญ ๋๋ฉด์ starting ์ง์ ์ผ๋ก ์ผ๊ณ , // ์ธ์ vertex ์์ด // ์ ์น ํด์ ธ ์๋ค๋ฉด, ๋์ ๋ค๋ฅธ ์์ผ๋ก ์น ํ๊ณ , // ๋ค๋ฅด๋ฉด ํต๊ณผ // ๊ฐ์ผ๋ฉด ์คํจ Vertex& s = m_Vertex[0]; s.m_Color = BLUE; return _IsBicolorable(0); } bool CBicoloring::_IsBicolorable(int from) { Vertex& s = m_Vertex[from]; Ints adjectives; GetAdjectiveVertex(from, adjectives); bool ret = false; for (size_t i = 0; i < adjectives.size(); ++i) { int to = adjectives[i]; Vertex& v = m_Vertex[to]; // ์ธ์ vertex ์์ด if (EMPTY == v.m_Color) // ์ ์น ํด์ ธ ์๋ค๋ฉด, ๋์ ๋ค๋ฅธ ์์ผ๋ก ์น ํ๊ณ , { v.m_Color = s.GetOppositeColor(); ret = _IsBicolorable(to); } else if (s.m_Color != v.m_Color) { // OK ret = _IsBicolorable(to); } else // ์ธ์ vertex ๊ฐ ๋์ ๊ฐ์ ์. ์ท... { ret = false; } if (!ret) { return false; } } return true; } int CBicoloring::GetAdjectiveVertex(int from, Ints& ints) { for (int to = 0; to < m_nVertexNum; ++to) { // edge ์ฐ๊ฒฐ๋์ด ์๊ณ , ์์ง ํ์ธ ์ ๋ vertex ๋ผ๋ฉด if (m_GraphEdges[from][to] && (m_Vertex[to].m_Color == EMPTY)) { ints.push_back(to); } } return (int)ints.size(); } string CBicoloring::Result() { if (IsBicolorable()) { return "BICOLORABLE.\n"; } else { return "NOT BICOLORABLE.\n"; } } /////////////////////////////////////////////////////////////// // CConsole class CConsole { public: static void ConsoleTest(istream& input, ostream& output); }; void CConsole::ConsoleTest(istream& input, ostream& output) { //ostrstream tempOutput; while (1) { int vertices = 0; input >> vertices; if (0 == vertices) { break; } int edges = 0; input >> edges; CBicoloring s; s.SetVerticesNum(vertices); int from; int to; for (int i = 0; i < edges; ++i) { input >> from >> to; s.Connect(from, to); } output << s.Result(); //tempOutput << ends; //output << tempOutput.str(); } }; } using namespace ATCode; #ifndef _UNIT_TEST int main() { CConsole::ConsoleTest(cin, cout); return 0; } #else // tests struct FixtureConsole { stringstream input; stringstream output; }; TEST_FIXTURE(FixtureConsole, ConsoleTest1) { input << "3\n3\n0 1\n1 2\n2 0\n0\n"; CConsole::ConsoleTest(input, output); CHECK_EQUAL("NOT BICOLORABLE.\n", output.str()); } TEST_FIXTURE(FixtureConsole, ConsoleTest2) { input << "9\n8\n0 1\n0 2\n0 3\n0 4\n0 5\n0 6\n0 7\n0 8\n0\n"; CConsole::ConsoleTest(input, output); CHECK_EQUAL("BICOLORABLE.\n", output.str()); } TEST_FIXTURE(FixtureConsole, ConsoleTest3) { input << "3\n2\n0 1\n1 2\n0\n"; CConsole::ConsoleTest(input, output); CHECK_EQUAL("BICOLORABLE.\n", output.str()); } TEST_FIXTURE(FixtureConsole, ConsoleTest4) { input << "3\n2\n0 2\n2 1\n0\n"; CConsole::ConsoleTest(input, output); CHECK_EQUAL("BICOLORABLE.\n", output.str()); } #endif /* @END_OF_SOURCE_CODE */
-
ํ๋ถ 2ํ๋ ๋ ๊ทธ๋ํ ๋ถ๋ถ์ ์ ๋๋ก ๊ณต๋ถ๋ฅผ ๋ชปํด์์ธ์ง ๊ทธ๋ํ๊ฐ ๋๋ ค์์.
-
์๋ฃ๋ Array๋ฅผ ์ด์ฉํด์ ํํํ๊ณ , ์ต์ด node๋ฅผ ๊ฒ์ ์์ผ๋ก ์น ํ๊ณ ์ฐ๊ฒฐ๋์ด์๋ node๋ค์ ์ฐพ์๊ฐ๋ฉฐ ์์ ์น ํ๋ค๊ฐ ์ด์ node๋ ๊ฐ์์์ ์ฐ๊ฒฐ๋ node๋ฅผ ๋ฐ๊ฒฌํ๋ฉด false๋ฅผ ๋๋ ค์ฃผ๋๋ก ํ์ต๋๋ค.
-
์ด๋ฒ์ ์์ค๊ฐ ๊น๋ํ์ง ๋ชปํ๊ฒ ๋์๋ค์ ใ _ใ ..
#include <stdio.h>
#define ever (;;)
enum COLOR {NONE, BLACK, WHITE};
struct node
{
bool use;
int color;
bool isLink[200];
}Matrix[200];
int n;
void InputData()
{
int l;
scanf("%d", &l);
for(int i = 0; i < n; i++ )
{
Matrix[i].color = NONE;
Matrix[i].use = false;
for(int j = 0; j < n; j++ )
{
Matrix[i].isLink[j] = false;
}
}
for(int i = 0; i < l; i++ )
{
int temp1, temp2;
scanf("%d %d", &temp1, &temp2);
Matrix[temp1].use = true;
Matrix[temp2].use = true;
Matrix[temp1].isLink[temp2] = true;
Matrix[temp2].isLink[temp1] = true;
}
}
int GetNextColor(int color)
{
color++;
if(color > WHITE) color = BLACK;
return color;
}
//////////////////////////////////////////////////////////////////////////
// no์ ์ฐ๊ฒฐ๋ node๋ค์ ์์ ๋ค๋ฅธ์์ผ๋ก ์น ํด์ฃผ๋ ํจ์.,
// ๋ง์ฝ node์ ์ด๋ฏธ ์์ด ์น ํด์ ธ ์๋ค๋ฉด,. no์ ์๊ณผ ๊ฐ์ผ๋ฉด false๋ฆฌํด
//////////////////////////////////////////////////////////////////////////
bool FillColor(int no, int color)
{
int nextColor = GetNextColor(color);
for(int i = 0; i < n; i++ )
{
if( Matrix[no].isLink[i] )
{
if( Matrix[i].color == color ) // ์ด๋ฏธ ์์ด ์น ํด์ ธ ์๋๋ฐ ๊ฐ๋ค๋ฉด..
{
return false;
}
else if( Matrix[i].color == NONE ) // ์์ด ์น ํด์ ธ ์์ง ์๋ค๋ฉด..
{
Matrix[i].color = nextColor; // no์ ๋ค๋ฅธ์์ ์น ํ๊ธฐ
if( FillColor(i, nextColor) == false ) // i์ ์ฐ๊ฒฐ๋ node๋ค ํ์ ์ํค๊ธฐ!
{
return false;
}
}
}
}
return true;
}
bool GetResult()
{
for(int i = 0; i < n; i++ )
{
if( Matrix[i].use )
{
Matrix[i].color = BLACK;
return FillColor(i, BLACK);
}
}
return true;
}
int main()
{
for ever
{
scanf("%d", &n);
if( n == 0 ) break;
InputData();
if( GetResult() == false )
{
printf("NOT ");
}
printf("BICOLORABLE.\n");
}
return 0;
}
-
๋ฐฐ์ด ๋ฐฐ์ด๋ก ๊ทธ๋ํ๋ฅผ ์ฒ๋ฆฌํ์ต๋๋ค
-
์์ค
public class Graph { private int pointCount; private boolean[][] nodes; private final int RED=1; private final int BLUE=2; public Graph(int pointCount) { this.pointCount = pointCount; nodes = new boolean[pointCount][pointCount]; for(int i=0;i<pointCount;i++){ for(int j=0;j<pointCount;j++){ nodes[i][j] = false; } } } public void insertNode(int fromPoint, int toPoint) { nodes[fromPoint][toPoint] = true; nodes[toPoint][fromPoint] = true; } public boolean checkBio() { //๋ฐฉ๋ฌธํ์ผ๋ฉด ์๊ฐ๋ฒํธ๊ฐ ์ค์ ๋์ด ์์ ์๋๋ฉด 0 int [] traveledPoint = new int[this.pointCount]; for(int i=0;i<pointCount;i++){ traveledPoint[i] = 0; } for(int fromPoint=0;fromPoint<pointCount;fromPoint++){ for(int toPoint=0;toPoint<pointCount;toPoint++){ //์์ ๊ณผ ์์ ์ ๊ฒ์ฌ์ด๋ผ๋ฉด skip if(fromPoint==toPoint) continue; //ํด๋น ๋ ธ๋๊ฐ mark ๋์ด ์์ผ๋ฉด ๊ฒ์ฌ ์ํ if(nodes[fromPoint][toPoint]){ //๋ง์ฝ ์์์ ์ ์๊น์ด ์์น ํด์ ธ ์์ผ๋ฉด ๊ธฐ๋ณธ์์ผ๋ก ์น ํจ if(traveledPoint[fromPoint]==0){ traveledPoint[fromPoint] = RED; } //๋ง์ฝ ์ข ๋ฃ์ ์ ์๊น์ด ์์น ํด์ ธ์์ผ๋ฉด ์์์ ๊ณผ ๋ฐ๋์ if(traveledPoint[toPoint] ==0){ traveledPoint[toPoint] = traveledPoint[fromPoint] == RED? BLUE:RED; } //์ข ๋ฃ์ ๊ณผ ์์์ ์ ์๊น์ด ๊ฐ์์ง ๊ฒ์ฌ ๋ง์ผ ๊ฐ๋ค๋ฉด false๋ฆฌํด if(traveledPoint[fromPoint] == traveledPoint[toPoint]){ return false; } } } } return true; } } -
ํ ์คํธ์ผ์ด์ค
import junit.framework.TestCase; public class GraphTestCase extends TestCase { public void testInitGraph(){ Graph graph = new Graph(3); graph.insertNode(0,1); graph.insertNode(1,2); graph.insertNode(2,0); assertFalse(graph.checkBio()); } public void testInitGraph2(){ Graph graph = new Graph(7); graph.insertNode(0,1); graph.insertNode(0,2); graph.insertNode(0,3); graph.insertNode(0,4); graph.insertNode(0,5); graph.insertNode(0,6); assertTrue(graph.checkBio()); } }