题目大意
有三种结点,发电站,中转站和消耗站。
因为是多源多汇的问题,所以建图时应该自己增加一个超级源,超级汇。
超级源到各个发电站的流量限制等于发点的量,
用的是Dinic算法2000ms的时间限制用了188ms,虽然没太优化效率还算不错
#include<iostream>
using namespace std;
struct Edge
{
int cap, flow;
};
Edge edges[200][200];
int size;
int visit[200], s , t;
int q[1000000], d[1000000];
//void init()
//{
// for(int i = 0; i < size; i++)
// {
// visit[i] = 0; d[i] = 0;
// for(int j = 0; j < size; j++)
// {
// edges[i][j].cap = -1; edges[i][j].flow = 0;
// }
// }
//}
int BFS()
{
int i, front, tail,temp;
bool flag;
for(i = 0; i < size + 2; i++)
{
visit[i] = 0;
}
front = 0; tail = 1;
q[front] = s;
visit[s] = 1; d[s] = 0;
while(front < tail)
{
temp = q[front];
front++;
flag = true;
for(i = 0; i < size + 2; i++)
{
if(!visit[i] && edges[temp][i].cap > edges[temp][i].flow)
{
q[tail] = i;
d[i] = d[temp] + 1;
visit[i] = 1;
if(i == t)
{
flag = false;
}
tail++;
}
}
if(!flag)
break;
}
return visit[t];
}
int DFS(int pos, int in)
{
if(in == 0 || pos == t) return in;
int flow = 0, temp, temp1 = in, f;
for(int i = 0; i < size + 2; i++)
{
if(d[i] == d[pos] + 1 && edges[pos][i].cap > edges[pos][i].flow)
{
temp = edges[pos][i].cap - edges[pos][i].flow;
if(temp < temp1)
f = DFS(i, temp);
else
f = DFS(i, temp1);
edges[pos][i].flow += f;
edges[i][pos].flow -= f;
flow += f;
temp1 -= f;
if(temp1 == 0)
break;
}
}
return flow;
}
int maxFlow()
{
//init();
int flow = 0;
while(BFS())
{
flow += DFS(s, 10000000);
}
return flow;
}
int main()
{
int faSize, haoSize, linkSize, i, j;
int start, end, value;
char temp[100];
while(scanf("%d", &size) != EOF)
{
s = size; t = size + 1;
scanf("%d%d%d", &faSize, &haoSize, &linkSize);
for(i = 0; i < size + 2; i++)
{
visit[i] = 0; d[i] = 0;
for(j = 0; j < size + 2; j++)
{
edges[i][j].cap = 0; edges[i][j].flow = 0;
}
}
//cout << linkSize << endl;
while(linkSize--)
{
scanf("%s",temp);
sscanf(temp,"(%d,%d)%d",&start,&end,&value);
//scanf("(%d,%d)%d", &start, &end, &value);
//cout << start << " " << end << " " << value;
edges[start][end].cap = value;
}
while (faSize--)
{
scanf("%s",temp);
sscanf(temp, "(%d)%d", &end, &value);
edges[s][end].cap = value;
}
while (haoSize--)
{
scanf("%s",temp);
sscanf(temp, "(%d)%d", &start, &value);
edges[start][t].cap = value;
}
cout << maxFlow() <<endl;
for(i = 0; i < size + 2; i++)
{
// visit[i] = 0; d[i] = 0;
// for(j = 0; j < size + 2; j++)
// {
// cout << edges[i][j].cap << " ";
// }
}
}
}
消耗站到超级汇的流量等于各个消耗站能消耗的量。
值得注意的是当有一个点有自己到自己的流量限制时完全可以忽略,
因为比较大的话也只会保持原来的流量,比较小的话就只能使流量变小。
选择不经过这个流量限制完全不会对结果产生影响。