记录编号 276468 评测结果 AAAA
题目名称 [ZOJ 2676]网络战争 最终得分 100
用户昵称 GravatarTenderRun 是否通过 通过
代码语言 C++ 运行时间 0.078 s
提交时间 2016-07-03 23:49:35 内存使用 1.65 MiB
显示代码纯文本
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <cmath>
using namespace std;
const int maxn=10010;
const int maxm=40010;
const double eps=1e-7;
const int INF=10000000;
int n,m,e[maxm][3];
int cnt,fir[maxn],to[maxm],nxt[maxm],ID[maxm];
double cap[maxn];
void addedge(int a,int b,double c,int id){
	nxt[++cnt]=fir[a];
	fir[a]=cnt;
	ID[cnt]=id;
	cap[cnt]=c;
	to[cnt]=b;
}

queue<int>q;
int dis[maxn];
bool BFS(int s,int t){
	memset(dis,0,sizeof(dis));
	dis[t]=1;q.push(t);
	while(!q.empty()){
		int x=q.front();q.pop();
		for(int i=fir[x];i;i=nxt[i])
			if(!dis[to[i]]){
				dis[to[i]]=dis[x]+1;
				q.push(to[i]);
			}
	}	
	return dis[s];
}

int fron[maxn];
int gap[maxn],path[maxn];
double ISAP(int s,int t){
	if(!BFS(s,t))return 0;
	for(int i=s;i<=t;i++)++gap[dis[i]];
	for(int i=s;i<=t;i++)fron[i]=fir[i];
	int p=s;
	double f,ret=0;
	while(dis[s]<=t){
		if(p==t){
			f=INF;
			while(p!=s){
				f=min(f,cap[path[p]]);
				p=to[path[p]^1];				
			}
			ret+=f;p=t;
			while(p!=s){
				cap[path[p]]-=f;
				cap[path[p]^1]+=f;
				p=to[path[p]^1];
			}
		}
		int &ii=fron[p];
		for(;ii;ii=nxt[ii])
			if(cap[ii]>eps&&dis[p]==dis[to[ii]]+1)
				break;
		if(ii)
			path[p=to[ii]]=ii;
		else{
			if(--gap[dis[p]]==0)break;
			int minn=t+1;
			for(int i=fir[p];i;i=nxt[i])
				if(cap[i]>eps)minn=min(minn,dis[to[i]]);
			++gap[dis[p]=minn+1];ii=fir[p];
			if(p!=s)p=to[path[p]^1];	
		}			
	}
	return ret;
}

int ch[maxm],ans;
void Init(){
	memset(fir,0,sizeof(fir));
	memset(gap,0,sizeof(gap));
	memset(ch,0,sizeof(ch));
	cnt=1;
}


double Solve(double lam){
	Init();
	double ret=0.0;
	for(int i=1;i<=m;i++){
		if(e[i][2]-lam<-eps){
			ret+=e[i][2]-lam;
			ch[i]=1;
		}
		else{
			addedge(e[i][0],e[i][1],e[i][2]-lam,i);
			addedge(e[i][1],e[i][0],e[i][2]-lam,i);
		}
	}
	ret+=ISAP(1,n);
	for(int i=2;i<=cnt;i++)
		if(fabs(cap[i])<eps&&ID[i])ch[ID[i]]=1;
	return ret;	
}

int main(){
#ifndef ONLINE_JUDGE
	freopen("networkwar.in","r",stdin);
	freopen("networkwar.out","w",stdout);
#endif
	while(true){
		scanf("%d%d",&n,&m);
		if(!n&&!m)break;
		for(int i=1;i<=m;i++)
			for(int j=0;j<=2;j++)
				scanf("%d",&e[i][j]);
		double lo=eps,hi=INF,lam;
		for(int t=1;t<=30;t++){
			lam=(lo+hi)/2;
			if(Solve(lam)>eps)
				lo=lam;
			else 
				hi=lam;
			if(hi-lo<eps)break;	
		}
		ans=0;
		for(int i=1;i<=m;i++)
			if(ch[i])ans+=1;
		printf("%d\n",ans);
		for(int i=1;i<=m;i++)
			if(ch[i])printf("%d ",i);
		printf("\n\n");		
	}
	return 0;	
}