zoukankan      html  css  js  c++  java
  • POJ 1639 Picnic Planning

      http://poj.org/problem?id=1639

      题目大意:给定一个图,求最小生成树,其中某个节点的度数小于K。

      这就是一个最小k限度生成树,我写了好久好久,也有我不熟悉STL的原因,CE了好久……

      求最小K度生成树的方法:首先去掉特殊点(v0),然后图会成为x个联通块,求x次最小生成树,然后将这x个生成树连接到v0上。

      每次寻找一个点p,满足点p不与v0相联系(边不在生成树上,不是不相连),且与点p相关的在生成树上的边大于点p到v0的距离,舍弃原来的边,并将点p与v0相连。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <vector>
    #include <algorithm>
    #include <stack>
    #include <queue>
    #include <deque>
    #include <map>
    #include <utility>
    #include <iterator>
    #include <cassert>
    #include <cctype>
    #include <list>
    #include <bitset>
    #include <cmath>
    #include <functional>
    #include <set>
    #include <sstream>
    #include <ctime>
    #define mn 301
    #define mm 1000
    #define inf ~0u>>1
    using namespace std;
    
    struct EDGE{
    	int pnt,dist;
    	EDGE *pre;
    	EDGE (){}
    	EDGE(int _pnt,int _dist,EDGE *_pre):pnt(_pnt),dist(_dist),pre(_pre){}
    }Edge[mm*2],*SP=Edge,*edge[mm];
    map<string,int> NameList;
    char place1[100],place2[100];
    int x,y,z,n,names=1,MST,belong[mn],size[mn],blocks,dist[mn],pre[mn],big[mn],K,Link[mn],Point[mn],Degree,places;
    bool use[mn][mn],vis[mn];
    
    inline void addedge(int a,int b,int c){
    	edge[a]=new(++SP)EDGE(b,c,edge[a]);
    	edge[b]=new(++SP)EDGE(a,c,edge[b]);
    }
    
    int NameOrder(char s[100]){
    	if(NameList.find(s)==NameList.end()) NameList[s]=++names;
    	else return NameList[s];
    	return names;
    }
    
    void Count_Connection_Blocks(int x){
    	vis[x]=true,belong[x]=blocks,size[blocks]++;
    	for(EDGE *j=edge[x];j;j=j->pre)
    		if(!vis[j->pnt]) Count_Connection_Blocks(j->pnt);
    }
    
    void Prim(int cur){	
    	for(int i=1;i<=names;i++) dist[i]=inf;
    	for(int i=1;i<=names;i++)
    		if(belong[i]==cur){
    			dist[i]=0;
    			break;
    		}
    	for(int k=1;k<=size[cur];k++){
    		int mind=inf,minp;
    		for(int i=1;i<=names;i++)
    			if(!vis[i] && mind>dist[i])
    				mind=dist[i],minp=i;
    		MST+=dist[minp],vis[minp]=true;
    		for(EDGE *j=edge[minp];j;j=j->pre)
    			if(!vis[j->pnt] && dist[j->pnt]>j->dist)
    				dist[j->pnt]=j->dist,pre[j->pnt]=minp;
    	}
    }
    
    void Mark(int u,int v,bool symble){
    	use[u][v]=symble,use[v][u]=symble;
    }
    
    void DP(int x,int fa){
    	pre[x]=fa;
    	for(EDGE *j=edge[fa];j;j=j->pre)
    		if(j->pnt==x){
    			if(fa!=1) big[x]=max(big[fa],j->dist);
    			else big[x]=0;
    			break;
    		}
    	for(EDGE *j=edge[x];j;j=j->pre)
    		if(use[x][j->pnt] && j->pnt!=fa) DP(j->pnt,x);
    }
    	
    int main(){
    	scanf("%d",&n);
    	NameList["Park"]=1;
    	for(int i=1;i<=n;i++){
    		scanf("%s%s%d",place1,place2,&z);
    		addedge(NameOrder(place1),NameOrder(place2),z);
    	}
    	scanf("%d",&K);
    	vis[1]=true;
    	for(int i=2;i<=names;i++)
    		if(!vis[i]){
    			blocks++;
    			Count_Connection_Blocks(i);
    		}
    	memset(vis,false,sizeof(vis));vis[1]=true;
    	for(int i=1;i<=blocks;i++) Prim(i);
    	for(int i=2;i<=n;i++) Mark(pre[i],i,true);
    	memset(Link,0x7f,sizeof(Link));
    	for(EDGE *j=edge[1];j;j=j->pre)
    		if(Link[belong[j->pnt]]>j->dist)
    			Link[belong[j->pnt]]=j->dist,Point[belong[j->pnt]]=j->pnt;
    	for(int i=1;i<=blocks;i++){
    		MST+=Link[i];
    		Mark(1,Point[i],true);
    	}
    	Degree=blocks;
    	addedge(0,1,0);
    	DP(1,0);
    	while(Degree<K){
    		int maxd=0,maxp=0;
    		for(EDGE *j=edge[1];j;j=j->pre)
    			if(!use[1][j->pnt] && big[j->pnt]-j->dist>maxd)
    				maxd=big[j->pnt]-j->dist,maxp=j->pnt;
    		if(!maxp) break;
    		MST-=maxd,Degree++;
    		int i=maxp;EDGE *j;
    		while(true){
    			for(j=edge[i];j;j=j->pre)
    				if(j->pnt==pre[i]) break;
    			if(j->dist==big[maxp]) break;
    			else i=pre[i];
    		}
    		Mark(i,pre[i],false);
    		pre[maxp]=1;DP(maxp,1);
    	}
    	printf("Total miles driven: %d\n",MST);
    	return 0;
    }
    

      

  • 相关阅读:
    webpack
    npm
    关于js click事件、touch事件的 screen 、client
    同源策略、jsonp、阻塞事件
    关于height、width、top
    新建空白图片
    配置环境
    异常02
    异常01
    集合框架08
  • 原文地址:https://www.cnblogs.com/Delostik/p/2120490.html
Copyright © 2011-2022 走看看