社区讨论
80分求调并查集
P1056[NOIP 2008 普及组] 排座椅参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mhjt69ee
- 此快照首次捕获于
- 2025/11/04 08:06 4 个月前
- 此快照最后确认于
- 2025/11/04 08:06 4 个月前
思路就是贪心 然后选出前k/l个最多的划分点 但我一开始没有想到答案的直接处理 而是使用二维数组打标记 两个点有多种情况 如果两个点都有自己的数字了 那就并查集直接合并 如果都没有数字的话就用++cnt 如果一个有一个没有就用有的覆盖没有的 最后计算所有划分点 最后用优先队列找出前k/l个 但是不知道为什么错了
CPP#include <bits/stdc++.h>
#define int long long
//标记切分属性 每一次选择最大的切分属性来切分
int m,n,k,l,d;
const int MAXN = 1e3+10;
int father[MAXN*2];
int a[MAXN][MAXN];
int cnt_idx[MAXN];
int cnt_col[MAXN];
void build(int n){
for(int i=1;i<=n;i++){
father[i]=i;
}
}
int find(int i){
if(father[i]!=i){
father[i]=find(father[i]);
}
return father[i];
}
void Union(int x,int y){
int fx = find(x);
int fy = find(y);
if(fx!=fy){
father[fx]=fy;
}
}
void printarr(){
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
std::cout<<a[i][j]<<" ";
}
std::cout<<'\n';
}
std::cout<<'\n';
for(int i=1;i<=m;i++){
std::cout<<cnt_idx[i];
}
std::cout<<'\n';
for(int j=1;j<=n;j++){
std::cout<<cnt_col[j];
}
}
struct Node{
int num,id;
};
struct cmp{
bool operator()(const Node& n1,const Node& n2){
return n1.num<n2.num;
}
};
inline void run(){
std::cin>>m>>n>>k>>l>>d;
//k 横着
//l 竖着
//d 有多少对
int cnt=1;
build(d);
for(int i=0,x1,y1,x2,y2;i<d;i++){
std::cin>>x1>>y1>>x2>>y2;
if(a[x1][y1]==0&&a[x2][y2]==0){
a[x1][y1]=cnt;
a[x2][y2]=cnt++;
}else{
if(a[x1][y1]!=0 && a[x2][y2]==0){
a[x2][y2]=a[x1][y1];
continue;
}
if(a[x2][y2]!=0 && a[x1][y1]==0){
a[x1][y1]=a[x2][y2];
continue;
}
Union(a[x1][y1],a[x2][y2]);
}
}
for(int i=1;i<m;i++){
for(int j=1;j<=n;j++){
if(a[i][j]==a[i+1][j] && a[i][j]!=0 && find(a[i][j])==find(a[i+1][j])){
cnt_idx[i]++;
}
}
}
for(int j=1;j<n;j++){
for(int i=1;i<=m;i++){
if(a[i][j]==a[i][j+1]&&a[i][j]!=0&&find(a[i][j+1])==find(a[i][j])){
cnt_col[j]++;
}
}
}
std::priority_queue<Node,std::vector<Node>,cmp> pq;
std::vector<int> ans;
for(int i=1;i<m;i++){
pq.push({cnt_idx[i],i});
}
while(k--){
ans.push_back(pq.top().id);
// std::cout<<pq.top().id<<" ";
pq.pop();
}
while(!pq.empty()){
pq.pop();
}
std::sort(ans.begin(),ans.end());
for(int i=0;i<ans.size();i++){
if(i==0){
std::cout<<ans[i];
}else{
std::cout<<" "<<ans[i];
}
}
ans.clear();
std::cout<<'\n';
for(int j=1;j<n;j++){
pq.push({cnt_col[j],j});
}
while(l--){
ans.push_back(pq.top().id);
pq.pop();
}
std::sort(ans.begin(),ans.end());
for(int i=0;i<ans.size();i++){
if(i==0){
std::cout<<ans[i];
}else{
std::cout<<" "<<ans[i];
}
}
// printarr();
//idx
}
signed main(){
std::ios::sync_with_stdio(0);
std::cout.tie(0);
std::cin.tie(0);
// freopen("P1056_2.in","r",stdin);
int T=1;
while(T--){
run();
}
return 0;
}
回复
共 0 条回复,欢迎继续交流。
正在加载回复...