hdu4966最小树形图
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #define REP(i,a,b) for(int i=a;i<=b;i++) #define MS0(a) memset(a,0,sizeof(a)) using namespace std; typedef long long ll; const int maxn=1000100; const int INF=1e9+10; int n,m; int a[52]; int c[2100],L1[2100],d[2100],L2[2100],money[2100]; int id[52][520]; int N; /// D-MST struct Edge { int u,v,w; };Edge e[maxn];int en; int in[25100]; int pre[25100],ID[25100],vis[25100]; /// D-MST 点的标号必须是0~N-1,不能改为0~N或1~N int D_MST(int rt,int n,int m) { int res=0; while(1){ REP(i,0,n-1) in[i]=INF; REP(i,1,m){ int u=e[i].u,v=e[i].v,w=e[i].w; if(w<in[v]&&u!=v){ pre[v]=u; in[v]=w; } } REP(i,0,n-1){ if(i==rt) continue; if(in[i]==INF) return -1; } int cntnode=0; memset(ID,-1,sizeof(ID)); memset(vis,-1,sizeof(vis)); in[rt]=0; REP(i,0,n-1){ res+=in[i]; int v=i; while(vis[v]!=i&&ID[v]==-1&&v!=rt){ vis[v]=i; v=pre[v]; } if(v!=rt&&ID[v]==-1){ for(int u=pre[v];u!=v;u=pre[u]) ID[u]=cntnode; ID[v]=cntnode++; } } if(cntnode==0) break; REP(i,0,n-1) if(ID[i]==-1) ID[i]=cntnode++; REP(i,1,m){ int v=e[i].v; e[i].u=ID[e[i].u]; e[i].v=ID[e[i].v]; if(e[i].u!=e[i].v) e[i].w-=in[v]; } n=cntnode; rt=ID[rt]; } return res; } /// s=0,u=0~N-1 ; e=1~en void build() { N=1; REP(i,1,n) REP(j,0,a[i]) id[i][j]=N++; en=0; REP(i,1,n) e[++en]=(Edge){0,id[i][0],0}; REP(i,1,m) e[++en]=(Edge){id[c[i]][L1[i]],id[d[i]][L2[i]],money[i]}; REP(i,1,n) REP(j,1,a[i]) e[++en]=(Edge){id[i][j],id[i][j-1],0}; } int solve() { return D_MST(0,N,en); } int main() { freopen("in.txt","r",stdin); while(cin>>n>>m,n||m){ REP(i,1,n) scanf("%d",&a[i]); REP(i,1,m) scanf("%d%d%d%d%d",&c[i],&L1[i],&d[i],&L2[i],&money[i]); build(); printf("%d\n",solve()); } return 0; }
没有AC不了的题,只有不努力的ACMER!