您的位置:首页 > 其它

ZOJ 2676 分数规划

2015-05-14 10:59 197 查看
zoj 2676 过了 sap的问题,准备找个好点的sap板子

#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#define eps 1e-5
#define maxn 500
using namespace std;
const int inf = 0x3f3f3f3f;
const int MAXN = 110;
const double esp = 1e-8;
int sign(double x){ return x<-esp?-1:(x>esp);}
int n, m, Max;
int S, N, T;
bool inde[maxn];

struct node
{
int u,v,cost;
}in[maxn];

struct Edge{
int u, v, nxt;
double f;
}edge[50101];
struct Edge_Info{
int a,b,c;
void input(){
scanf("%d%d%d",&a,&b,&c);
}
}edge_info[550];
bool vis[MAXN];
int h[MAXN], vh[MAXN];
int head[MAXN], idx;

void AddEdge(int a,int b,double f){
edge[idx].u = a, edge[idx].v = b, edge[idx].f = f;
edge[idx].nxt = head[a], head[a] = idx++;
edge[idx].u = b, edge[idx].v = a, edge[idx].f = 0;
edge[idx].nxt = head[b], head[b] = idx++;
}

double dfs(int u,double flow){
if(u == T) return flow;
int tmp = h[u]+1; double sum = flow;
for(int i = head[u]; ~i; i = edge[i].nxt){
if( sign(edge[i].f) > 0 && (h[ edge[i].v ]+1 == h[u])){
double p = dfs( edge[i].v, min(sum,edge[i].f));
edge[i].f -= p, edge[i^1].f += p, sum -= p;
if( sign(sum)==0 || h[S]==N ) return flow-sum;
}
}
for(int i = head[u]; ~i; i = edge[i].nxt ){
if( sign(edge[i].f) > 0 ) tmp = min(tmp,h[ edge[i].v ] );
}
if( --vh[ h[u] ] == 0 ) h[S] = N;
else ++vh[ h[u]=tmp+1 ];
return flow-sum;
}
double sap(){
double maxflow = 0;
memset(h,0,sizeof(h));
memset(vh,0,sizeof(vh));
vh[0] = N;
while( h[S] < N ) maxflow += dfs( S,inf );
return maxflow;
}

void DFS(int u){
vis[u] = true;
for(int i = head[u]; ~i; i = edge[i].nxt){
if( sign(edge[i].f) > 0 && !vis[ edge[i].v ] )
DFS( edge[i].v );
}
}

void dfs(int u)
{
vis[u] = 1;
for(int i = head[u];i != -1;i = edge[i].nxt)
{
if( sign(edge[i].f) > 0 && !vis[ edge[i].v ] )
dfs( edge[i].v );
}
}

double build(double g)
{
memset( head, -1, sizeof(head));
idx = 0;
double all=0;

for(int i=1;i<=m;i++)
{
double temp=in[i].cost*1.0-g;
if( sign(temp) <0 )
all+=temp;
else
AddEdge(in[i].u,in[i].v,temp),AddEdge(in[i].v,in[i].u,temp);

}
return all;
}

bool judge(double mid)
{
double temp=build(mid);
double res=sap();
res+=temp;
if(res<eps) return true;
else return false;
}

void output(double ans)
{
int a[maxn];
memset(inde,false,sizeof(inde));
memset( head, -1, sizeof(head));
idx = 0;
for(int i=1;i<=m;i++)
{
double temp=in[i].cost*1.0-ans;
if( sign(temp) <0 )
inde[i]=true;
else  AddEdge(in[i].u,in[i].v,temp),AddEdge(in[i].v,in[i].u,temp);

}
memset(vis,0,sizeof(vis));
sap();
dfs(1);
int counter=0;
for(int i=1;i<=m;i++)
{
int tempa=in[i].u;
int tempb=in[i].v;
if((vis[tempa]&&!vis[tempb])||(!vis[tempa]&&vis[tempb]))
inde[i]=true;
}
for(int i=1;i<=m;i++)
if(inde[i])
a[++counter]=i;
printf("%d\n",counter);
for(int i=1;i<counter;i++)
printf("%d ",a[i]);
printf("%d\n\n",a[counter]);
}

int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
S=1;T=n;N=n;
int ma=0;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&in[i].u,&in[i].v,&in[i].cost);
if(in[i].cost>ma) ma=in[i].cost;
}
double left=0;
double right=ma*1.0;
while(right-left>eps)
{
double mid=(left+right)*0.5;
if(judge(mid))
right=mid;
else left=mid;
}
output(left);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: