您的位置:首页 > 其它

zoj 2760 How Many Shortest Path floyd+最大流+处理的技巧

2017-04-26 11:03 429 查看
自己一开始没有想到枚举边。。

然后在Floyd的时候发现不可以。。

然后就还是用 addedge来求最短路。。、

然后又发现还是很麻烦,,对于dt的要反着求。、

然后看别人的题解。。

发现还是用Floyd  只是之后  用两次for循环就可以枚举边;了。。//看了别人的,,他们一开始存边的时候还是会存-1,,然后再在Floyd中判断,,是否联通

还有,自己好像有点把Floyd中的  路径和流混了,,,所以老是觉得不可以。。

而且看了http://blog.csdn.net/zxy_snow/article/details/6760882

感觉太强了,,

确实用了Floyd 之后会导致原来图的边多了。。

所以他就用memcpy  弄一个b来维护原本的边,  然后他的不是用求ds 和dt  他只是在建网络流图的时候只按照s为起点来建。。

这样的话求出来也是一样的。。。

看来自己还是做题少啊、。、(vj,还是挂了。。。)

#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a));
#define sf scanf
#define pf printf
#define LL long long
#define bug1 cout<<"bug1"<<endl;
#define bug2 cout<<"bug2"<<endl;
#define bug3 cout<<"bug3"<<endl;

const int maxn=205;
const int INF=1e9;

struct Edge {
int from, to, cap, flow;
};

bool operator < (const Edge& a, const Edge& b) {
return a.from < b.from || (a.from == b.from && a.to < b.to);
}

struct Dinic {
int n, m, s, t;
vector<Edge> edges;
vector<int> G[maxn];
bool vis[maxn];
int d[maxn];
int cur[maxn];

void init(int n) {
for(int i = 0; i < n; i++) G[i].clear();
edges.clear();
}

void ClearFlow() {
for(int i = 0; i < edges.size(); i++) edges[i].flow = 0;
}

void addedge(int from, int to, int cap) {
edges.push_back((Edge){from, to, cap, 0});
edges.push_back((Edge){to, from, 0, 0});
m = edges.size();
G[from].push_back(m-2);
G[to].push_back(m-1);
}

bool BFS() {
memset(vis, 0, sizeof(vis));
queue<int> Q;
Q.push(s);
vis[s] = 1;
d[s] = 0;
while(!Q.empty()) {
int x = Q.front(); Q.pop();
for(int i = 0; i < G[x].size(); i++) {
Edge& e = edges[G[x][i]];
if(!vis[e.to] && e.cap > e.flow) {
vis[e.to] = 1;
d[e.to] = d[x] + 1;
Q.push(e.to);
}
}
}
return vis[t];
}

int DFS(int x, int a) {
if(x == t || a == 0) return a;
int flow = 0, f;
for(int& i = cur[x]; i < G[x].size(); i++) {
Edge& e = edges[G[x][i]];
if(d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap-e.flow))) > 0) {
e.flow += f;
edges[G[x][i]^1].flow -= f;
flow += f;
a -= f;
if(a == 0) break;
}
}
return flow;
}

int maxflow(int s, int t) {
this->s = s; this->t = t;
int flow = 0;
while(BFS()) {
memset(cur, 0, sizeof(cur));
flow += DFS(s, INF);
}
return flow;
}

vector<int> Mincut() {
vector<int> ans;
for(int i = 0; i < edges.size(); i++) {
Edge& e = edges[i];
if(vis[e.from] && !vis[e.to] && e.cap > 0) ans.push_back(i);
}
return ans;
}

void Reduce() {
for(int i = 0; i < edges.size(); i++) edges[i].cap -= edges[i].flow;
}
};

Dinic g;

int n;
int dist[maxn][maxn];
int b[maxn][maxn];
void floyd(){
for(int k=0;k<n;++k){
for(int i=0;i<n;++i){
for(int j=0;j<n;++j){
if(dist[i][k]!=-1&&dist[k][j]!=-1){
if(dist[i][j]==-1){
dist[i][j]=dist[i][k]+dist[k][j];
}
else
dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]);
}
}
}
}
}

int main(){
while(~sf("%d",&n)){
for(int i=0;i<n;++i){
for(int j=0;j<n;++j){
sf("%d",&dist[i][j]);
if(i==j){
dist[i][j]=0;
}
}
}
int s,t;sf("%d%d",&s,&t);
memcpy(b,dist,sizeof(dist));
floyd();
g.init(n);
int dst=dist[s][t];
for(int i=0;i<n;++i){
if(dist[s][i]==-1)continue;
for(int j=0;j<n;++j){
if(b[i][j]!=-1&&dist[s][j]!=-1&&dist[s][i]+b[i][j]==dist[s][j]){
g.addedge(i,j,1);
}
}
}
int ans=g.maxflow(s,t);
pf("%d\n",ans);
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: