原题:
很久很久以前,在一个名叫算法王国的地方,有一位非常聪明的鸡科学家,他的名字叫做阿鸡。阿鸡一直致力于研究计算机科学中的各种问题,希望能够用自己的知识来造福算法王国的居民。
这一天,阿鸡接到了国王的任务,需要他帮忙组织一场选拔赛。参加选拔赛的有 2 位选手,他们需要回答 m 个选择题,每个选择题都只有 L 或者 R 两个选项。阿鸡仔细观察了选手们的答题情况,发现了一个有趣的现象:如果将选手看作图中的点,两个点之间的边权可以表示为两位选手答题不同的数量。
阿鸡意识到,这就是一个经典的最小生成树问题!如果他能够找到这张图的最小生成树,就可以用最小的代价将所有选手连接起来,组成一个紧密的团队。这样一来,选拔赛的目的就达到了,国王也一定会对他刮目相看。
于是,阿鸡决定向算法王国最优秀的程序员们发出挑战,看谁能够在最短的时间内求出这张图的最小生成树。他相信,这次的比赛不仅能够选拔出最优秀的选手,还能让大家在解决问题的过程中互相学习,共同进步。
阿鸡满怀信心地期待着比赛的结果,他知道,只要大家齐心协力,算法王国一定会变得更加美好。
现在,就让我们一起来帮助阿鸡完成这个任务吧!你能够在最短的时间内求出这张图的最小生成树吗?
第一行一个整数 t 表示数据组数。
每组数据第一行两个整数 m 和 n,含义如题。
接下来 n 行每行一个长度为 m 的 LR 串,表示一个选手的答案。
每组数据输出一行一个整数表示答案。
2
4 5
LRRL
RRRR
RLLL
LLLL
RLRL
4 4
RLRR
LRRL
LRLR
LRLL
6
5
chicken_le.in / chicken_le.out
对于 30% 的数据 n≤2000;
对于另外 20% 的数据 m≤15;
对于另外 20% 的数据 m≤17;
对于 100% 的数据,t≤10,m≤20,n 之和不超过 200000,m 超过 17 的数据不超过 3 组。
我的代码:(TLE)
#include<bits/stdc++.h>
using namespace std;
int tasks,comps,qs;
struct line{
int end1,end2,length;
};
struct node{
vector<int> pathways;
} nod[210000];
long long answers[210000];
vector<line> lineList;
bool searched[210000]={false};
bool compSmaller(line a, line b){
return a.length<b.length;
} //最佳状态
int binaryDifference(long long a,long long b){
int diffRaw=a^b;
int cnt=0;
while(diffRaw){
diffRaw=diffRaw&(diffRaw-1);
cnt++;
}
return cnt;
} //最佳状态
long long processData(string a){
int length=a.length();
long long result=0;
for(int i=length-1;i>=0;i--){
result+=(a[i]=='R'?1:0)*(1<<(length-i-1));
}
return result;
}
bool dfs(int a, int prevs=-1){
if(searched[a])return true;
node cur=nod[a];
searched[a]=true;
for(int k:cur.pathways){
if(k==prevs)continue;
if(dfs(k,a))return true;
}
return false;
} //最佳状态
int kruskal(){
int res=0;
int lines=0;
int targ=comps-1;
int id=0;
while(lines<targ){
memset(searched,0,comps);
line a=lineList[id];
int node1=a.end1,node2=a.end2,cost=a.length;
nod[node1].pathways.push_back(node2);
nod[node2].pathways.push_back(node1);
if(dfs(node1)){
nod[node1].pathways.pop_back();
nod[node2].pathways.pop_back();
}else{
lines++;
res+=cost;
}
id++;
}
for(int i=0;i<comps;i++){
nod[i].pathways.clear();
}
return res;
} //可优化
int main(){
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(false);
//code here
cin>>tasks;
for(int tt=0;tt<tasks;tt++){
int solution=0;
cin>>qs>>comps;
string cache;
for(int i=0;i<comps;i++){
cin>>cache;
answers[i]=processData(cache);
}
for(int i=0;i<comps-1;i++){
for(int j=i+1;j<comps;j++){
lineList.push_back({i,j,binaryDifference(answers[i],answers[j])});
}
}
sort(lineList.begin(),lineList.end(),compSmaller);
solution=kruskal();
cout<<solution<<endl;
lineList.clear();
}
return 0;
}
求dl调代码