HDU4966

来源:互联网 发布:centos 6.8 安装pptp 编辑:程序博客网 时间:2024/06/07 04:19
#include <stdio.h>//这是别人的题解 #include <string.h>//A了 #include <iostream>#include <algorithm>#include <math.h>using namespace std;const int INF = 100000000;const int MAXN = 1010; //点数const int MAXM = 1010000;//边数struct EDGE{ int u,v,cost;}edge[MAXM];int v;int pre[MAXN],visit[MAXN],sum[MAXN],in[MAXN],a[MAXN],id[MAXN];int edgenum;void add_edge(int u,int v,int cost){EDGE E={u,v,cost};edge[++edgenum]=E;//cout<<v<<" "<<cost<<endl;}int hash(int i,int j){return sum[i-1]+j;}int zhuliu(int root,int n,int m,EDGE edge[])//root为0 {int res=0,tn;//cout<<m<<endl;while(1){// cout<<m<<endl;for(int i=0;i<=n;i++)//n不对吧! in[i]=INF;//不是啦,循环所有点 //cout<<"*****"<<endl;    for(int i=1;i<=m;i++){//cout<<edge[i].u<<" "<<edge[i].v<<" "<<edge[i].cost<<endl;if(edge[i].v!=edge[i].u&&edge[i].cost<in[edge[i].v]){in[edge[i].v]=edge[i].cost;pre[edge[i].v]=edge[i].u;    }} //cout<<pre[3]<<endl;for(int i=0;i<=n;i++){//cout<<i<<" "<<in[i]<<endl;if(i!=root&&in[i]==INF)return -1;}memset(id,-1,sizeof(id));memset(visit,-1,sizeof(visit));in[root]=0;for(int i=0;i<=n;i++)res+=in[i];//cout<<res<<endl;//找自环tn=0;/*****/for(int i=0;i<=n;i++){int u=i;while(u!=root&&visit[u]!=i&&id[u]==-1)//一直向前赋值,既然源节点不是root,那么他就是一个环 {visit[u]=i;u=pre[u];}if(u!=root&&id[u]==-1) {for(int v=pre[u];u!=v;v=pre[v]) id[v]=tn;id[u]=tn++;    }}//cout<<tn<<endl;if(tn==0)break;//按边更新 for(int i=0;i<=n;i++)if(id[i]==-1)id[i]=tn++;//for(int i=0;i<=n;i++)//cout<<id[i]<<endl;//for(int i=1;i<=m;i++)//cout<<edge[i].u<<" "<<edge[i].v<<endl;for(int i = 1;i <=m;)//缩点 ,建立新图 {v = edge[i].v;//cout<<i<<" "<<edge[i].u<<" "<<edge[i].v<<endl;edge[i].u = id[edge[i].u];//是一个环中 edge[i].v = id[edge[i].v];if(edge[i].u != edge[i].v)edge[i++].cost -= in[v];elseswap(edge[i],edge[--m+1]);//减边,而且把edge[i]放到后面。。。太绝了 }n=tn-1;    root=id[root];    //cout<<tn-1<<endl;    }    return res;}int main(){int n,m;while(scanf("%d%d",&n,&m),n+m){edgenum=0;int x1,y1,x2,y2,cos; for(int i=1;i<=n;i++){sum[0]=0;cin>>a[i];        a[i]++;    sum[i]=sum[i-1]+a[i];}for(int i=1;i<=n;i++){//<<hash(i,1)<<endl;add_edge(0,hash(i,1),0);}for(int i=1;i<=n;i++){for(int j=1;j<=a[i]-1;j++)//高等级到低等级为0 add_edge(hash(i,j+1),hash(i,j),0);}for(int i=1;i<=m;i++)//x1门课y1等级 {cin>>x1>>y1>>x2>>y2>>cos; y1++;y2++;//cout<<hash(x1,y1)<<" "<<hash(x2,y2)<<endl;add_edge(hash(x1,y1),hash(x2,y2),cos);}//for(int i=1;i<=edgenum;i++)//cout<<edge[i].u<<" "<<edge[i].v<<" "<<edge[i].cost<<endl;int result=zhuliu(0,sum[n],edgenum,edge);//只用考虑这些边 cout<<result<<endl;}return 0;}

0 0
原创粉丝点击