공부/알고리즘2

maxflow bipar

pflower 2014. 11. 6. 09:58

#include <iostream>

#include <iostream>

#include <fstream>



using namespace std;



#define UP(i, j) flowInput(((i - 1) * n + j) * 2, ((i - 2) * n + j) * 2 - 1, 1); // 위와 연결

#define DOWN(i, j) flowInput(((i - 1) * n + j) * 2, (i * n + j) * 2 - 1, 1); // 아래와 연결

#define LEFT(i, j) flowInput(((i - 1) * n + j) * 2, ((i - 1) * n + (j - 1)) * 2 - 1, 1); // 왼쪽과 연결

#define RIGHT(i, j) flowInput(((i - 1) * n + j) * 2, ((i - 1) * n + (j + 1)) * 2 - 1, 1); // 오른쪽과 연결



int v, e;


struct Link

{


Link(int u, int capacity)

{


this->u = u;

this->flow = 0;

this->capacity = capacity;

this->cosine = NULL;

next = NULL;


}


int u;


int capacity;


int flow;


Link *cosine;




Link *next;




};





#include<iostream>

using namespace std;


struct Item

{

int u;

int localResidue;


Item *next;

};



Link **graph;

int *seen;

int *parent;

//int seen[1000];

//int parent[1000];

Item queue[1000];


Item *front;

Item *back;


//int front;

//int back;


int min(int a, int b)

{

return (a<b) ? a : b;

}



void push(Item val){

if (front == NULL)

{

front = new Item(val);

back = front;

}

else 

{

back->next = new Item(val);

back = back->next;


}

}

Item pop(){

if (back != NULL)

{

Item ret(*front);

Item* temp = front;

front = front->next;

if (front == NULL)

back = NULL;

delete temp;

return ret;

}

}

bool queueEmpty()

{

return back == NULL;

}




void doFlow(int head, int flow)

{


for (Link* temp = graph[parent[head]]; temp != NULL; temp = temp->next)

{

if (temp->u == head)

{


temp->flow += flow;

temp->cosine->flow -= flow;


}


}


}




int run = 1;




void bfs(int n)

{


Item item;

item.u = n;

item.localResidue = 987654321;

item.next = NULL;

push(item);


Item nextItem;

nextItem.u = 0;

nextItem.localResidue = 987654321;

nextItem.next = NULL;



while (!queueEmpty())

{

Item i = pop();

seen[i.u] = 2;

//cout << i << endl;


for (Link *temp = graph[i.u]; temp != NULL; temp = temp->next)

{

if (seen[temp->u] == 0 && temp->capacity > temp->flow)

{

parent[temp->u] = i.u;

nextItem.u = temp->u;

nextItem.localResidue = min(i.localResidue, temp->capacity - temp->flow);

push(nextItem);

seen[temp->u] = 1;



if (nextItem.u == v + 1)

{

int head = v + 1;

while (head != 0)

{

doFlow(head, nextItem.localResidue);

head = parent[head];

}

run = 1;

return;


}


}


}


}




if (nextItem.u != v + 1)

{

run = 0;

}


}




void bfs_all()

{


for (int i = 0; i < v; i++)

if (seen[i] == 0)

bfs(i);


}



fstream fin;


int flow();

void flowInput(int a, int b, int c);


int main()

{

int n, m, k, flowAmount = 0;

char tmp;


fin.open("input.txt");


fin >> n >> m >> k;


v = n + m;


graph = new Link*[v + 2];

seen = new int[v + 2];

parent = new int[v + 2];


memset(graph, 0, sizeof(Link*) * (v + 2));

for(int i = 0; i < k; i++)


for(int i = 0; i < k; i++)

{

int a, b;

fin >> a >> b;

flowInput(0, a, 1);

flowInput(a, n + b, 1);

flowInput(n + b, n + m + 1, 1);

}

int ret = flow();

std::cout << "Max Flow is " << ret << endl;

}


void flowInput(int a, int b, int c)

{


//int a, b, c;


std::cout << a << " " << b << " " << c << endl;


Link *aLink = NULL;

Link *bLink = NULL;



bool isExist = false;


if (graph[a] == NULL)

{

graph[a] = new Link(b, c);

aLink = graph[a];

}

else

{

Link *temp = NULL;

for (temp = graph[a]; temp != NULL; temp = temp->next)

{

if (temp->u == b)

{

isExist = true;

temp->capacity = c;

}


}


if (!isExist)

{


for (temp = graph[a]; temp->next != NULL; temp = temp->next);

temp->next = new Link(b, c);

aLink = temp->next;


}


}


isExist = false;


if (graph[b] == NULL)

{

graph[b] = new Link(a, 0);

bLink = graph[b];


}

else

{

Link *temp = NULL;


for (temp = graph[b]; temp != NULL; temp = temp->next)

{


if (temp->u == a)

{

isExist = true;

break;

}


}


if (!isExist)

{

for (temp = graph[b]; temp->next != NULL; temp = temp->next);

temp->next = new Link(a, 0);

bLink = temp->next;


}


}

if (aLink && bLink)

{


aLink->cosine = bLink;

bLink->cosine = aLink;


}

}


int flow()

{


while (run)

{

front = NULL;

back = NULL;

/*

front = 0;

back = 0;*/

memset(seen, 0, sizeof(int) * (v + 2));

memset(parent, -1, sizeof(int) * (v + 2));

//memset(parent, -1, sizeof(parent));

//memset(seen, 0, sizeof(seen));

bfs(0);


while (!queueEmpty())

pop();


}




//for (int i = 1; i <= v; i++)

//{

// std::cout << parent[i] << endl;

//}




int result = 0;

for (Link *temp = graph[0]; temp != NULL; temp = temp->next)

{

result += temp->flow;

}




return result;




}