JZOJ.5327【NOIP2017模拟8.21】四驱兄弟
题目要求晶片之间连接不能形成环,然后求连成的边的第K小值。
INF就代表不存在第K小值的边。
我们可以想到这最优结果一定是一棵最小生成树。
由Kruskal算法,这第K小值就是这棵最小生成树的第K小的边。
然后我们就输出前n条边的值就好了,不足n的剩下就输出INF
字符串什么的随便hash一下或者离散什么的转成数字就好了
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <algorithm> 6 #include <map> 7 #define N 1000002 8 using namespace std; 9 map<string,int>qwq; 10 int n,m,ans,tmp[N],f[N],top,u[N],cnt; 11 bool power[N]; 12 char a[6],b[6]; 13 struct data{ 14 int l,r; 15 long long v; 16 }car[N]; 17 bool comp(const struct data a,const struct data b){ 18 return a.v<b.v; 19 } 20 int find(int x){ 21 if (f[x]==x) return x; 22 else f[x]=find(f[x]); 23 return f[x]; 24 } 25 int main(){ 26 scanf("%d%d",&n,&m); 27 cnt=0; 28 for (int i=1,u=0,v=0;i<=m;i++){ 29 scanf("%lld",&car[i].v); 30 scanf(" %s %s",a,b); 31 if (qwq[(string)a]==0) qwq[(string)a]=++cnt; 32 if (qwq[(string)b]==0) qwq[(string)b]=++cnt; 33 car[i].l=qwq[(string)a]; 34 car[i].r=qwq[(string)b]; 35 } 36 for (int i=1;i<=cnt;i++) 37 f[i]=i; 38 sort(car+1,car+1+m,comp); 39 top=0; 40 for (int i=1;i<=m;i++){ 41 int c=find(car[i].l); 42 int d=find(car[i].r); 43 if (c!=d){ 44 f[c]=d; 45 tmp[++top]=i; 46 } 47 } 48 for (int i=1;i<=min(top,n);i++) 49 printf("%lld\n",car[tmp[i]].v); 50 for (int i=min(top,n)+1;i<=n;i++) 51 printf("INF\n"); 52 return 0; 53 }