↓ Skip to main content
  1. Posts/

poj 1789 Truck History (mst,prim)

·852 words·2 mins
Note: This article is available in Chinese only. 本文暂无英文版本。 View original

poj1789题目链接

题意:其实题目不难理解。。。直接按照定义去搞就行了。。。

思路:由于距离在分母上。。所以要quality最大。。。就是要分母最小。。。

然后由于题目中说每一种类型的type只能由其他一种派生出来。。。我们可以把这个派生关系看做一条边。。。把每种类型看成点。。

这样就构成了一棵树。。。先o(nn7)预处理出权值。。。然后最小生成树即可。。。

这种给了坐标距离作为权值的图一定是稠密图。。。图小用kruskal糊弄一下就过去了。。。图大的话还是乖乖的用prim吧。。。

然而仍然 TLE???wtf??

最后发现。。因为我习惯用string…但是又怕卡cin…所以做法是scanf读入字符数组然后再赋值给string..

然而这种操作不知为何神tm慢。。。。。(求指教)

以至于:[

要知道。。。这题时限2s啊。。。为毛能差1s多。。。也就是说时间的瓶颈完全是在读入了orz…

代码实现
  1/* ***********************************************
  2Author :111qqz
  3Created Time :2016年07月14日 星期四 00时13分04秒
  4File Name :code/poj/1789.cpp
  5 ************************************************ */
  6
  7#include <cstdio>
  8#include <cstring>
  9#include <iostream>
 10#include <algorithm>
 11#include <vector>
 12#include <queue>
 13#include <set>
 14#include <map>
 15#include <string>
 16#include <cmath>
 17#include <cstdlib>
 18#include <ctime>
 19#define fst first
 20#define sec second
 21#define lson l,m,rt<<1
 22#define rson m+1,r,rt<<1|1
 23#define ms(a,x) memset(a,x,sizeof(a))
 24typedef long long LL;
 25#define pi pair < int ,int >
 26#define MP make_pair
 27
 28using namespace std;
 29const double eps = 1E-8;
 30const int dx4[4]={1,0,0,-1};
 31const int dy4[4]={0,-1,1,0};
 32const int inf = 0x3f3f3f3f;
 33const int N=2E3+7;
 34int n,m;
 35int f[N];
 36int v[N];
 37char st[N][10];
 38//string st[N];
 39int matrix[N][N];
 40
 41void init()
 42{
 43    for ( int i = 0 ; i < n; i++)
 44	for ( int j = 0 ; j <n ; j++)
 45	    matrix[i][j] = inf;
 46}
 47int getw(char * a,char * b)
 48{
 49    int res = 0 ;
 50    for ( int i = 0 ; i < 7 ; i++)
 51	if (a[i]!=b[i]) res++;
 52    return res;
 53}
 54void prim()
 55{
 56    bool flag[N];
 57    int nearest[N];
 58    int adjecent[N];
 59    int i,j;
 60    int min;
 61    int sum=0;
 62
 63    for ( int i = 0 ; i < n ; i++) flag[i] = false;
 64    flag[0] = true;
 65    for(i = 1; i < n; ++i)
 66    {
 67	nearest[i] = matrix[0][i];
 68	adjecent[i] = 0;
 69    }
 70    int count = n;
 71    while(--count)
 72    {
 73	min = inf;
 74	j = 0;
 75	for(i = 0; i < n; ++i)
 76	{
 77	    if(!flag[i] && nearest[i] < min)
 78	    {
 79		min = nearest[i];
 80		j = i;
 81	    }
 82	}
 83	sum+=matrix[j][adjecent[j]];
 84
 85	flag[j] = true;
 86	for(i = 0; i < n; ++i)
 87	{
 88	    if(!flag[i] && matrix[i][j] < nearest[i])
 89	    {
 90		nearest[i] = matrix[i][j];
 91		adjecent[i] = j;
 92	    }
 93	}
 94    }
 95    printf("The highest possible quality is 1/%d.\n",sum);
 96}
 97
 98int main()
 99{
100#ifndef  ONLINE_JUDGE
101    freopen("code/in.txt","r",stdin);
102#endif
103
104    while (~scanf("%d",&n))
105    {
106	if (n==0) break;
107	init();
108
109	for ( int i = 0 ; i < n ; i++)
110	{
111	  //  char tmp[10];
112	    scanf("%s",st[i]);
113	//    st[i]=tmp;
114	}
115
116	for ( int i = 0 ; i < n ; i++)
117	    for ( int j = 0 ; j < n ; j++)
118		if (i<j)
119		{
120
121		    matrix[i][j]=matrix[j][i]=getw(st[i],st[j]);
122
123		}
124
125	prim();
126    }
127
128#ifndef ONLINE_JUDGE
129    fclose(stdin);
130#endif
131    return 0;
132}

Related

poj 2349 Arctic Network (mst)

·615 words·2 mins
Poj2349题目链接 题意:给出n个点坐标。。。然后可以建s个卫星基站。。。有卫星基站的地方之间可以互相免费通信。。现在要建一些无线电通讯线路(不同于卫星基站,是另一种通信方式),两个点之间线路的代价是他们的距离。。。问最小距离是多少。。。使得任意两个点之间都可以直接或者间接联系。。。

poj 1751 Highways (最小生成树,空间卡常数有毒啊)

·607 words·2 mins
poj1751题目链接 题意:一开始有一些边,然后添加一些边,使得代价之和最小。 思路:先把给定的边merge掉。。然后计算其余可以添加的边。。。接下来就是最小生成树。。。 然而因为多开了一个750*750的数组空间被卡了常。。。毫无人性。。。。

poj 1679 The Unique MST (判断mst的唯一性,次小生成树)

·548 words·2 mins
poj1679 题意:问最小生成树是否唯一。。 思路:求一下次小生成树。。。如果无解,或者次小生成树的权值之和和最小生成树的权值之和不同,那么唯一,否则不唯一。1A 代码实现 1/* *********************************************** 2Author :111qqz 3Created Time :2016年07月12日 星期二 16时16分52秒 4File Name :code/poj/1679.cpp 5************************************************ */ 6#include <cstdio> 7#include <cstring> 8#include <iostream> 9#include <algorithm> 10#include <vector> 11#include <queue> 12#include <set> 13#include <map> 14#include <string> 15#include <cmath> 16#include <cstdlib> 17#include <ctime> 18#define fst first 19#define sec second 20#define lson l,m,rt<<1 21#define rson m+1,r,rt<<1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair < int ,int > 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=105; 32int n,m; 33int ans; 34int f[N]; 35struct Edge 36{ 37 int u,v,w; 38 int in; 39 void input() 40 { 41 scanf("%d%d%d",&u,&v,&w); 42 } 43 bool operator < (Edge b)const 44 { 45 return w<b.w; 46 } 47}edge[N*N]; 48void init() 49{ 50 for ( int i = 1 ; i <= n ; i++) f[i] = i; 51} 52int root ( int x) 53{ 54 if (x!=f[x]) f[x] = root(f[x]); 55 return f[x]; 56} 57void merge( int x,int y) 58{ 59 int rx = root(x); 60 int ry = root(y); 61 if (rx==ry) return ; 62 f[rx] = ry; 63} 64void kruskal( int k) 65{ 66 for ( int i = 1 ; i <= n; i++) f[i] = i; 67 int cnt = 0 ; 68 int cur = 0 ; 69 for ( int i = 1; i <= m ; i++) 70 { 71 int u = edge[i].u; 72 int v = edge[i].v; 73 int w = edge[i].w; 74 if (i==k) continue; 75 if (root(u)==root(v)) continue; 76 merge(u,v); 77 cnt++; 78 cur+=w; 79 if (cnt>=n-1) break; 80 } 81 // cout<<"cnt:"<<cnt<<endl; 82 if (cnt<n-1) return ; 83 ans = min(ans,cur); 84} 85int main() 86{ 87 #ifndef ONLINE_JUDGE 88 freopen("code/in.txt","r",stdin); 89 #endif 90 int T; 91 scanf("%d",&T); 92 while (T--) 93 { 94 scanf("%d%d",&n,&m); 95 init(); 96 for ( int i = 1; i <= m ; i++) edge[i].input(); 97 sort(edge+1,edge+m+1); 98 int cnt = 0 ; 99 int mst = 0 ; 100 for ( int i = 1 ; i <= m ; i++) 101 { 102 int u = edge[i].u; 103 int v = edge[i].v; 104 int w = edge[i].w; 105 if (root(u)==root(v)) continue; 106 edge[i].in = 1; 107 merge(u,v); 108 cnt++; 109 mst+=w; 110 } 111 ans = inf; 112 for ( int i = 1 ; i <= m ; i++) 113 { 114 if (edge[i].in==0) continue; 115 //cout<<"i:"<<i<<endl; 116 kruskal(i); 117 } 118 // cout<<"mst:"<<mst<<endl; 119 // cout<<"ans:"<<ans<<endl; 120 if (ans==inf) 121 { 122 printf("%d\n",mst); 123 }else 124 { 125 if (ans==mst) puts("Not Unique!"); 126 else printf("%d\n",mst); 127 } 128 } 129 #ifndef ONLINE_JUDGE 130 fclose(stdin); 131 #endif 132 return 0; 133}

ural 1416. Confidential (次小生成树模板题)

·730 words·2 mins
URAL1416 题意:次小生成树模板题 思路:用Kruskal求最小生成树,标记用过的边。求次小生成树时,依次枚举用过的边,将其去除后再求最小生成树,得出所有情况下的最小的生成树就是次小的生成树。复杂度o(m2)。。。貌似有其他优化。。。

hdu 4607 Park Visit (树的直径,推公式)

·748 words·2 mins
hdu4607题目链接 题意:给出一棵树。。。边权都为1. m个查询。。每个查询给一个k,表示只访问k个点。。。问每次的最小路径和是多少。。。 思路:我们发现。。会使路径和变大的一个不利因素是折返。。也就是访问某景点后。。必须要回去才能继续前进。。这样的距离是2倍。。那为了使得路径和尽可能小。。我们就尽量不要访问这样的点。。。而不是这样的点一定在直径上。。。以及我们还发现。。。不在直径上的点。。 。。不管深度如何(深度的意思是说,与和该点最近的直径上的点的距离),距离的贡献是一样的。。都是2倍。。所以我们可以推出一个公式。。。如果树的直径是d,那么k<=d+1的时候,答案为k-1,否则答案为d+(k-d-1)*2。。。