#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
struct node
{
int end;
int flow;
int cap;
struct node* next;
struct node* pair;
};
typedef struct node node;
int queue[1000];
int front;
int tail;
int pd[1000];
int pb[1000];
int visited[1000];
struct node* adj;
int v,e;
int n;
char map[100][100];
node* insert_adj(int a, int b, int w,int c);
void dfs(int i);
int bfs(int i);
int inqueue(int a);
int dequeue();
int main(void)
{
int i,sum=0,j;
int num=0;
int startpoint;
struct node *temp1,*temp2;
FILE* fin = fopen("escape_input8.txt","r");
node* t;
//fscanf (fin,"%d %d",&v,&e);
if (fin==NULL){
printf ("파일이없음\n");
exit(0);
}
fscanf (fin,"%d",&n);
v=n*n*2;
adj = (node*)malloc(sizeof(node)*(v+3));
//adj = (node*)malloc(sizeof(node)*(n*n*2+2));
for (i=0;i<=v+2;i++){
adj[i].end=-1;
adj[i].flow=0;
adj[i].cap=0;
adj[i].next=NULL;
}
for (i=0;i<n;i++)
fscanf (fin,"%s",map[i]);
num=1;
startpoint=0;
for (i=0;i<n;i++)
{
for (j=0;j<n;j++)
{
if (map[i][j] == '1')//start
{
temp1=insert_adj(0,num,0,1);
temp2=insert_adj(num,0,0,0);
temp1->pair = temp2;
temp2->pair = temp1;
startpoint++;
}
if (i!=0)//위쪽연결
{
temp1=insert_adj(num+1,num-2*n,0,1);
temp2=insert_adj(num-2*n,num+1,0,0);
temp1->pair = temp2;
temp2->pair = temp1;
}
if (i != n-1) // 아래쪽연결
{
temp1=insert_adj(num+1,num+2*n,0,1);
temp2=insert_adj(num+2*n,num+1,0,0);
temp1->pair = temp2;
temp2->pair = temp1;
}
if (j != 0) // 왼쪽연결
{
temp1=insert_adj(num+1,num-2,0,1);
temp2=insert_adj(num-2,num+1,0,0);
temp1->pair = temp2;
temp2->pair = temp1;
}
if (j!=n-1)// 오른쪽연결
{//problem
temp1=insert_adj(num+1,num+2,0,1);
temp2=insert_adj(num+2,num+1,0,0);
temp1->pair = temp2;
temp2->pair = temp1;
}
//innode -> outnode
temp1=insert_adj(num,num+1,0,1);
temp2=insert_adj(num+1,num,0,0);
temp1->pair = temp2;
temp2->pair = temp1;
if (i==0 || i == n-1 || j == 0 || j == n-1) // end
{
temp1=insert_adj(num+1,n*n*2+1,0,1);
temp2=insert_adj(n*n*2+1,num+1,0,0);
temp1->pair = temp2;
temp2->pair = temp1;
}
num+=2;
}
}
/*
for (i=0;i<e;i++)
{
struct node *temp1,*temp2;
fscanf (fin,"%d %d %d",&a,&b,&c);
temp1=insert_adj(a,b,0,c);
temp2=insert_adj(b,a,0,0);
temp1->pair = temp2;
temp2->pair = temp1;
//insert_adj(b,a,w);
}
*/
memset(visited,-1,sizeof(visited));
memset(pd,-1,sizeof(pd));
memset(pb,-1,sizeof(pb));
memset(visited,-1,sizeof(visited));
/*
for (int i=0;i<v;i++)
{
node* t=&adj[i];
while(t!=NULL)
{
printf ("<%d %d %d (%d)> ",i,t->end,t->cap,t->pair->cap);
t=t->next;
}
printf ("\n");
}
*/
while(1)
{
int minflow;
memset(visited,-1,sizeof(visited));
memset(queue,0,sizeof(queue));
front=tail=0;
inqueue(0);
minflow=bfs(0);
printf ("minflow : %d \n\n",minflow);
if ( visited[v+1] == -1 )
break;
else
{
int child = v+1;
int parent = pb[child];
node* t=&adj[child];
while (parent != 0)
{
t=&adj[parent];
while(t!=NULL){
if (t->end == child)
break;
t=t->next;}
t->flow += minflow;
t->pair->flow += -minflow;
child=parent;
parent = pb[child];
}
/*
while(t!=NULL){
if (t->end == parent)
break;
t=t->next;}
t->flow += -minflow;
t->pair->flow += +minflow;
*/
t=&adj[0];
while(t!=NULL){
if (t->end == child)
break;
t=t->next;}
t->flow += minflow;
t->pair->flow += -minflow;
}
}
node* temp = &adj[v+1];
while (temp!= NULL)
{
sum += temp->pair->flow;
temp = temp->next;
}
printf ("start : %d\n",startpoint);
printf ("sum : %d\n",sum);
if (startpoint == sum)
printf ("escape success\n");
else
printf ("escape fail\n");
return 0;
}
node* insert_adj(int a, int b, int w,int c){
node* temp;
node* z;
if (adj[a].end == -1){
adj[a].end=b;
adj[a].flow=w;
adj[a].cap=c;
adj[a].next=NULL;
return &adj[a];
}
temp=&adj[a];
while(temp->next != NULL)
{
if (temp->end == b)
{
temp->cap=c;
return temp;
}
temp=temp->next;
}
if (temp->end == b)
{
temp->cap=c;
return temp;
}
z = (node*)malloc(sizeof(node));
z->end=b;
z->flow=w;
z->cap=c;
z->next=NULL;
temp->next=z;
return z;
}
int bfs(int i)
{
int z = dequeue();
int min=987654321;
while( z!=-987654321)
{
node* t = &adj[z];
while(t!=NULL &&t->end != -1)
{
if (t->cap-t->flow > 0 && visited[t->end] == -1)
{
//printf ("%d %d\n",t->end,t->cap - t->flow);
if (t->cap - t->flow <min)
min=t->cap-t->flow;
if (t->end == v+1){
visited[t->end] = 1;
pb[t->end]=z;
return min;
}
visited[t->end] = 0;
pb[t->end] = z;
inqueue(t->end);
}
t=t->next;
}
visited[z] = 1;
z=dequeue();
}
return min;
}
void dfs(int i)
{
if (visited[i] != -1)
return;
else
{
node* t=&adj[i];
visited[i]=1;
while( t!=NULL &&t->end != -1 )
{
if (visited[t->end] == -1){
pd[t->end]=i;
dfs(t->end);
}
t=t->next;
}
}
}
int inqueue(int a)
{
queue[tail++]=a;
return 0;
}
int dequeue()
{
if (front == tail)
return -987654321;
return queue[front++];
}
'알고2' 카테고리의 다른 글
Race 자동차 경주 대회 (0) | 2014.11.05 |
---|---|
bipartite matching (0) | 2014.11.05 |
max flow (0) | 2014.10.15 |
dfsbfs (0) | 2014.10.08 |
dijkstra (0) | 2014.10.08 |