Code: Select all
#include <stdio.h>
#include <stdlib.h>
#define MAXV 100 /* maximum number of vertices */
#define MAXDEGREE 50 /* maximum outdegree of a vertex */
#define QUEUESIZE 1000
#define X 0 /* x-coordinate index */
#define Y 1 /* y-coordinate index */
#define TRUE 1
#define FALSE 0
typedef int bool;
typedef struct {
int q[QUEUESIZE+1]; /* body of queue */
int first; /* position of first element */
int last; /* position of last element */
int count; /* number of queue elements */
} queue;
typedef struct {
int edges[MAXV+1][MAXDEGREE]; /* adjacency info */
int degree[MAXV+1]; /* outdegree of each vertex */
int nvertices; /* number of vertices in the graph */
int nedges; /* number of edges in the graph */
} graph;
typedef struct {
int v; /* neighboring vertex */
int capacity; /* capacity of edge */
int flow; /* flow through edge */
int residual; /* residual capacity of edge */
} edge;
typedef struct {
edge edges[MAXV][MAXDEGREE]; /* adjacency info */
int degree[MAXV]; /* outdegree of each vertex */
int nvertices; /* number of vertices in the graph */
int nedges; /* number of edges in the graph */
} flow_graph;
int min (int a,int b){
if (a > b)
return b;
else
return a;
}
int init_queue(queue *q)
{
q->first = 0;
q->last = QUEUESIZE-1;
q->count = 0;
}
int enqueue(queue *q, int x)
{
if (q->count >= QUEUESIZE)
printf("Warning: queue overflow enqueue x=%d\n",x);
else {
q->last = (q->last+1) % QUEUESIZE;
q->q[ q->last ] = x;
q->count = q->count + 1;
}
}
int dequeue(queue *q)
{
int x;
if (q->count <= 0) printf("Warning: empty queue dequeue.\n");
else {
x = q->q[ q->first ];
q->first = (q->first+1) % QUEUESIZE;
q->count = q->count - 1;
}
return(x);
}
int empty(queue *q)
{
if (q->count <= 0) return (TRUE);
else return (FALSE);
}
int initialize_graph(flow_graph *g)
{
int i; /* counter */
g -> nvertices = 0;
g -> nedges = 0;
for (i=0; i<MAXV; i++) g->degree[i] = 0;
}
int insert_flow_edge(flow_graph *g, int x, int y,bool directed, int w)
{
if (g->degree[x] > MAXDEGREE)
printf("Warning: insertion(%d,%d) exceeds degree bound\n",x,y);
g->edges[x][g->degree[x]].v = y;
g->edges[x][g->degree[x]].capacity = w;
g->edges[x][g->degree[x]].flow = 0;
g->edges[x][g->degree[x]].residual = w;
g->degree[x] ++;
if (directed == FALSE)
insert_flow_edge(g,y,x,TRUE,w);
else
g->nedges ++;
}
int read_flow_graph(flow_graph *g,int directed,int c,int p)
{
int i,n; /* counter */
int m; /* number of edges */
int x,y,w; /* placeholder for edge and weight */
int count=0;
int sink;
sink=c+p+2;
initialize_graph(g);
for (i=1;i<=c;i++){
scanf("%d",&w);
insert_flow_edge(g,1,i+1,directed,w);
count++;
}
for (i=1; i<=p; i++) {
scanf("%d",&m);
if (m<=c&&m>0)
for(n=0;n<m;n++){
scanf("%d",&x);
if (x<=c&&x>0)
insert_flow_edge(g,x+1,c+i+1,directed,1);
}
insert_flow_edge(g,c+i+1,sink,directed,1);
}
g->nvertices=sink;
}
edge *find_edge(flow_graph *g, int x, int y)
{
int i; /* counter */
for (i=0; i<g->degree[x]; i++)
if (g->edges[x][i].v == y)
return( &g->edges[x][i] );
return(NULL);
}
int add_residual_edges(flow_graph *g)
{
int i,j; /* counters */
for (i=1; i<=g->nvertices; i++)
for (j=0; j<g->degree[i]; j++)
if (find_edge(g,g->edges[i][j].v,i) == NULL)
insert_flow_edge(g,g->edges[i][j].v,i,TRUE,0);
}
int print_flow_graph(flow_graph *g)
{
int i,j; /* counters */
for (i=1; i<=g->nvertices; i++) {
printf("%d: ",i);
for (j=0; j<g->degree[i]; j++)
printf(" %d(%d,%d,%d)",g->edges[i][j].v,
g->edges[i][j].capacity,
g->edges[i][j].flow,
g->edges[i][j].residual);
printf("\n");
}
}
bool processed[MAXV]; /* which vertices have been processed */
bool discovered[MAXV]; /* which vertices have been found */
int parent[MAXV]; /* discovery relation */
bool finished = FALSE; /* if true, cut off search immediately */
int initialize_search(flow_graph *g)
{
int i; /* counter */
for (i=1; i<=g->nvertices; i++) {
processed[i] = FALSE;
discovered[i] = FALSE;
parent[i] = -1;
}
}
int bfs(flow_graph *g, int start)
{
queue q; /* queue of vertices to visit */
int v; /* current vertex */
int i; /* counter */
init_queue(&q);
enqueue(&q,start);
discovered[start] = TRUE;
while (empty(&q) == FALSE) {
v = dequeue(&q);
for (i=0; i<g->degree[v]; i++)
if (valid_edge(g->edges[v][i]) == TRUE) {
if (discovered[g->edges[v][i].v] == FALSE) {
enqueue(&q,g->edges[v][i].v);
discovered[g->edges[v][i].v] = TRUE;
parent[g->edges[v][i].v] = v;
}
}
}
}
bool valid_edge(edge e)
{
if (e.residual > 0) return (TRUE);
else return(FALSE);
}
int find_path(int start,int end,int parents[])
{
if ((start == end) || (end == -1))
printf("\n%d",start);
else {
find_path(start,parents[end],parents);
printf(" %d",end);
}
}
int path_volume(flow_graph *g, int start, int end, int parents[])
{
edge *e; /* edge in question */
edge *find_edge();
if (parents[end] == -1) return(0);
e = find_edge(g,parents[end],end);
if (start == parents[end])
return(e->residual);
else
return( min(path_volume(g,start,parents[end],parents), e->residual) );
}
int augment_path(flow_graph *g, int start, int end, int parents[], int volume)
{
edge *e; /* edge in question */
edge *find_edge();
if (start == end) return;
e = find_edge(g,parents[end],end);
e->flow += volume;
e->residual -= volume;
e = find_edge(g,end,parents[end]);
e->residual += volume;
augment_path(g,start,parents[end],parents,volume);
}
int netflow(flow_graph *g, int source, int sink)
{
int volume; /* weight of the augmenting path */
add_residual_edges(g);
initialize_search(g);
bfs(g,source);
volume = path_volume(g, source, sink, parent);
while (volume > 0) {
augment_path(g,source,sink,parent,volume);
initialize_search(g);
bfs(g,source);
volume = path_volume(g, source, sink, parent);
}
}
int main(void)
{
flow_graph g; /* graph to analyze */
int source, sink; /* source and sink vertices */
int flow; /* total flow */
int i,j,tmp; /* counter */
int c,p;
scanf("%d%d",&c,&p);
while (c != 0 && p != 0){
read_flow_graph(&g,TRUE,c,p);
source=1;
sink=2+c+p;
netflow(&g,source,sink);
flow = 0;
for (j=0; j<g.degree[i+1]; j++){
if(g.edges[1][j].residual != 0){
flow=1;
}
}
if(flow == 0){
printf("1\n");
for (i=1;i<=c;i++){
for (j=0; j<g.degree[i+1]; j++){
if(g.edges[i+1][j].residual == 0){
tmp=g.edges[i+1][j].v;
tmp = tmp -c -1;
printf("%d ",tmp);
}
}
printf("\n");
}
}
else
printf("0\n");
scanf("%d%d",&c,&p);
}
//print_flow_graph(&g);
system("pause");
}