有度限制的最小生成树。解法网上很多,就不再叙述了。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=1e2+9,inf=5e7;
char a[maxn][maxn];
int n,m,limit;
int head[maxn],lon,visit[maxn],dist[maxn],distfrom[maxn];
bool flag[maxn];
struct
{
int to,next,w,use;
}e[maxn*maxn<<1];
void edgeini()
{
memset(head,-1,sizeof(head));
lon=-1;
}
void edgemake(int from,int to,int w)
{
e[++lon].to=to;
e[lon].w=w;
e[lon].next=head[from];
e[lon].use=0;
head[from]=lon;
}
int get(int &t)
{
for(int i=1;i<t;i++)
if(strcmp(&a[t][1],&a[i][1])==0)
{
t--;
return i;
}
return t;
}
int prim(int t)
{
int key[maxn],ff[maxn],from[maxn];
memset(key,50,sizeof(key));
memset(ff,0,sizeof(ff));
key[t]=0;
ff[t]=1;
visit[t]=t;
for(int k=head[t];k!=-1;k=e[k].next)
{
int u=e[k].to;
if(key[u]>e[k].w)
{
key[u]=e[k].w;
from[u]=k;
}
}
int ans=0;
while(1)
{
int tmp=inf,now;
for(int i=1;i<=n;i++)
if(key[i]<tmp&&!ff[i]&&!visit[i])
{
tmp=key[i];
now=i;
}
if(tmp==inf) return ans;
ans+=tmp;
ff[now]=1;
visit[now]=t;
e[from[now]].use=1;
e[from[now]^1].use=1;
for(int k=head[now];k!=-1;k=e[k].next)
{
int u=e[k].to;
if(key[u]>e[k].w)
{
key[u]=e[k].w;
from[u]=k;
}
}
}
}
void dfs(int t,int from,int mm,int kk)
{
for(int k=head[t];k!=-1;k=e[k].next)
{
int u=e[k].to;
if((!e[k].use)||(u==from)) continue;
if(e[k].w>mm)
{
dist[u]=e[k].w;
distfrom[u]=k;
dfs(u,t,e[k].w,k);
}
else
{
dist[u]=mm;
distfrom[u]=kk;
dfs(u,t,mm,kk);
}
}
}
int prim()
{
int ans=0;
memset(visit,0,sizeof(visit));
memset(flag,0,sizeof(flag));
visit[m]=m;
int sum=0;
for(int i=1;i<=n;i++)
if(!visit[i])
{
ans+=prim(i);
sum++;
}
for(int i=1;i<=sum;i++)
{
int tmp=inf,now;
for(int k=head[m];k!=-1;k=e[k].next)
{
if(e[k].w<tmp&&!flag[visit[e[k].to]])
{
tmp=e[k].w;
now=k;
}
}
flag[visit[e[now].to]]=1;
e[now].use=1;
e[now^1].use=1;
ans+=tmp;
}
for(int i=sum+1;i<=limit;i++)
{
memset(dist,50,sizeof(dist));
dfs(m,-1,0,-0);
int tmp=0,now,nowk;
for(int k=head[m];k!=-1;k=e[k].next)
{
if(e[k].use) continue;
if(dist[e[k].to]-e[k].w>tmp)
{
tmp=dist[e[k].to]-e[k].w;
now=k;
nowk=distfrom[e[k].to];
}
}
if(tmp==0) return ans;
else
{
e[now].use=1;
e[now^1].use=1;
e[nowk^1].use=0;
e[nowk].use=0;
ans-=tmp;
}
}
return ans;
}
int main()
{
// freopen("in.txt","r",stdin);
while(scanf("%d",&n)!=EOF)
{
memset(a,0,sizeof(a));
edgeini();
int mm;
for(int i=1,k=0,w;i<=n;i++)
{
scanf("%s",&a[++k][1]);
int t=get(k);
scanf("%s",&a[++k][1]);
scanf("%d",&w);
int s=get(k);
edgemake(t,s,w);
edgemake(s,t,w);
mm=k;
}
n=mm;
scanf("%d",&limit);
for(m=1;;m++) if(strcmp(&a[m][1],"Park")==0) break;
printf("Total miles driven: ");
cout<<prim()<<endl;
}
return 0;
}