• poj1639


    有n个巨人要去Park聚会。巨人A和先到巨人B那里去,然后和巨人B一起去Park。B君是个土豪,他家的停车场很大,可以停很多车,但是Park的停车场是比较小。只能停k辆车。现在问你在这个限制条件下。居然到达Park的最短距离-------------------------------------------------------------------------------------分割线

    如果把那个条件去掉。那么就是就是求最小生成树。加上那个条件其实就是求顶点度数限制为k的最小生成树。做法

    1.忽略顶点V0。我们对其他顶点做一次最小生成树,此时形成一颗森林。

    2.对步骤1中形成的每一颗最小生成树离顶点最近的点连起来。此时顶点的度数为m.

    3.由m度->m+1度

    (1)先dp预处理出当前生成树中与顶点V0到Vi的路径中与V0不关联的权值最大的边。dp[i].d记录的是权值,dp[i].u和dp[i].v记录的是边两边的点。

    (2)对于每一个不在生成树的<v0,v>把他们加进去最小生成树中,那么久会生成一个环。我们把环中的最大的权值删去。即1中得到的dp[v].d。就会形成m+1个度

    (3)对于(2)中我们枚举每一个顶点v。当minnum=min(g[v0][v]-dp[v].d)最小的时候。点v就是所求的点。 (4)重复步骤(3)直到k。其实当某一步的minnum>=0的时候就可以停止算法了。因为就算在增加度数生成树的权值也不会减小

    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    #include<algorithm>
    #include<map>
    #include<set>
    #include<vector>
    using namespace std;
    const int INF=0x3f3f3f3f;
    const int maxn=22;
    struct Edge
    {
    	int u,v,d;
    	Edge (){}
    	Edge(int a,int b,int c):u(a),v(b),d(c){} 
    	bool operator <(const Edge &e) const{
    	return d<e.d;}
    };
    int n,m,k;
    int cnt;
    int ans;
    int parent[maxn];
    map<string,int>nodes;
    vector<Edge>edges;
    int g[maxn][maxn];
    bool tree[maxn][maxn];
    int minEdge[maxn];
    Edge dp[maxn];
    int find(int p)
    {
    	if(p==parent[p])
    	return parent[p];
    	return parent[p]=find(parent[p]);
    }
    void un(int p,int q)
    {
    	parent[find(p)]=find(q);
    }
    void kruskal()
    {
    	sort(edges.begin(),edges.end());
    	for(int i=0;i<edges.size();i++)
    	{
    		int p=edges[i].u;
    		int q=edges[i].v;
    		if(p==1||q==1)
    		continue;
    		if(find(p)!=find(q))
    		{
    			un(p,q);
    			tree[p][q]=tree[q][p]=1;
    			ans+=edges[i].d;
    		}
    	}
    }
    void dfs(int cur,int pre)
    {
    	for(int i=2;i<=cnt;i++)
    	{
    		if(i==pre||!tree[cur][i])
    		continue;
    		if(dp[i].d==-1)
    		{
    			if(dp[cur].d>g[cur][i])
    			dp[i]=dp[cur];
    			else
    			{
    				dp[i].u=cur;
    				dp[i].v=i;
    				dp[i].d=g[cur][i];
    			}
    		}
    		dfs(i,cur);
    	}
    }
    void slove()
    {
    	int keyPoint[maxn];
        //memset(keyPoint,0,sizeof(keyPoint)); 
    	for(int i=2;i<=cnt;i++)
    	{
    		if(g[1][i]!=INF)
    		{
    			int color=find(i);
    			if(minEdge[color]>g[1][i])
    			{
    				minEdge[color]=g[1][i];
    				keyPoint[color]=i;
    				
    			}
    		}
    	}
    	for(int i=1;i<=cnt;i++)
    	{
    		if(minEdge[i]!=INF)
    		{
    			m++;
    			tree[1][keyPoint[i]]=tree[keyPoint[i]][1]=1;
    			ans+=g[1][keyPoint[i]];
    		}
    	}
    	for(int i=m+1;i<=k;i++)
    	{
    		memset(dp,-1,sizeof(dp));
    		dp[1].d=-INF;
    		for(int j=2;j<=cnt;j++)
    			if(tree[1][j])
    			dp[j].d=-INF;
    			dfs(1,-1);
    			int idx,minnum=INF;
    			for(int j=2;j<=cnt;j++)
    			{
    				if(minnum>g[1][j]-dp[j].d)
    				{
    					minnum=g[1][j]-dp[j].d;
    					idx=j;
    				}
    			}
    			if(minnum>=0)
    			break;
    			tree[1][idx]=tree[idx][1]=1;
    			tree[dp[idx].u][dp[idx].v]=tree[dp[idx].v][dp[idx].u]=1;
    			ans+=minnum;		
    	}
    }
    void init()
    {
    	memset(g,INF,sizeof(g));
    	memset(tree,0,sizeof(tree));
    	memset(minEdge,INF,sizeof(minEdge));
    	m=0;
    	cnt=1;
    	ans=0;
    	nodes["Park"]=1;
    	for(int i=0;i<maxn;i++)
    	parent[i]=i;
    }
    int main()
    {
    	scanf("%d",&n);
    	string s1,s2;
    	int d;
    	init();
    	for(int i=1;i<=n;i++)
    	{
    		cin>>s1>>s2>>d;
    		if(!nodes[s1])
    		nodes[s1]=++cnt;
    		if(!nodes[s2])
    		nodes[s2]=++cnt;
    		int u=nodes[s1];
    		int v=nodes[s2];
    		edges.push_back(Edge(u,v,d));
    		g[u][v]=g[v][u]=min(g[u][v],d);
    	}
    	scanf("%d",&k);
    	kruskal();
        slove();
    	printf("Total miles driven: %d
    ",ans);
    	return 0; 
    }
    

      



  • 相关阅读:
    Android strings.xml中定义字符串显示空格
    Android各国语言对照表(values-xxx)
    SimInfo获取(MCC, MNC, PLMN)
    Android APN
    Android studio 运行java程序
    [MyBatis]DAO层只写接口,不用写实现类
    idea代码调试debug篇
    比较分析 Spring AOP 和 AspectJ 之间的差别
    maven进阶:一个多模块项目
    Maven最佳实践:划分模块
  • 原文地址:https://www.cnblogs.com/NaCl/p/9580107.html
Copyright © 2020-2023  润新知