POJ 2175
消负权法。最小费用最大流的充要条件是,增广路没有负圈。所以这道题就是找到一个负圈,然后绕着路自己增广一周就好了。注意这里用的是,floyd算法去寻找负圈,要用类似链式储存的方式,来进行保存前面的节点。#include<iostream>#include<cstring>#include<algorithm>#include<cmath>...
·
消负权法。
最小费用最大流的充要条件是,增广路没有负圈。
所以这道题就是找到一个负圈,然后绕着路自己增广一周就好了。
注意这里用的是,floyd算法去寻找负圈,要用类似链式储存的方式,来进行保存前面的节点。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b) for(int i=a;i<b;i++)
#define dw(i,a,b) for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
using namespace std;
typedef pair<int, int> pir;
int n, m;
int model[205][205];
bool used[305];
int g[305][305];
int prevv[305][305];
int xi[105], yi[105];
int xj[105], yj[105];
int wi[105],wj[105];
void solve()
{
int m1 = n + m + 1;
up(i,0,m1)fill(g[i],g[i]+m1,1e9);
up(j, 0, m)
{
int sum = 0;
up(i, 0, n)
{
int dist = fabs(xi[i] - xj[j]) + fabs(yi[i] - yj[j]) + 1;
g[i][n + j] = dist;
if(model[i][j]>0)//有流量,才会有反向费用
g[n + j][i] = -dist;
sum += model[i][j];//每个隧道的总人数
}
if (sum > 0)g[n + m][n + j] = 0;//有流量,那么汇点到节点就有反向边
if (sum < wj[j])g[n + j][n + m] = 0;//没有满流,有正向边
}
up(i, 0, m1)
up(j, 0, m1)
prevv[i][j] = i;//预处理,每个点的头结点都是自己,
up(k, 0, m1) //要先从k开始
{
up(i, 0, m1)
{
up(j, 0, m1)
{
if (g[i][j] > g[i][k] + g[k][j])//松弛条件
{
g[i][j] = g[i][k] + g[k][j];
prevv[i][j] = prevv[k][j];//链式储存
if (i == j&&g[i][j]<0)//如果此时形成环了
{
memset(used, false, sizeof(used));
for (int v = i; !used[v]; v = prevv[i][v])
{
used[v] = true;
if (v >= n)
model[prevv[i][v]][v - n]++;
else model[v][prevv[i][v] - n]--;
}//负权增广
printf("SUBOPTIMAL\n");
up(x,0,n)
{
up(y,0,m)
{
printf("%d%c", model[x][y], y + 1 != m ? ' ' : '\n');
}
}
return;
}
}
}
}
}
cout << "OPTIMAL\n" << endl;
}
int main()
{
cin >> n >> m;
up(i, 0, n)
{
cin >> xi[i] >> yi[i] >> wi[i];
}
up(i, 0, m)
{
cin >> xj[i] >> yj[i] >> wj[i];
}
up(i, 0, n)
{
up(j, 0, m)
{
cin >> model[i][j];
}
}
solve();
return 0;
}
更多推荐
已为社区贡献6条内容
所有评论(0)