- 给n个点,m条边,问是不是一个完全多部图,意思就是能不能分成k组,每组之内两两点没有边连接,但是组之间,任意两点都是有边连接的。直接做不好做,但是发现如果取巧,将原图连通的边看作不连通,不连通的边看作连通,然后用并查集分块,这样每个块内间两点都是必然有边的,此时判定块内所有边是不是不连通的就好了。每次的复杂度都是O(n^2).
代码:
#include<iostream>
#include<fstream>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdio.h>
#include<utility>
#include<algorithm>
#include<map>
#include<stack>
#include<set>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn = 1005;
const int mod = 1e9+7;
const int INF = 1<<30;
int g[maxn][maxn], pre[maxn];
void init( ){
memset(g, 0, sizeof(g));
for(int i=0; i<maxn; i++)
pre[i] = i;
}
int f(int k){
if(pre[k] != k)
return pre[k] = f(pre[k]);
return k;
}
int main( ){
//freopen("input.txt", "r", stdin);
int T;
scanf("%d", &T);
while(T--)
{
init();
int n, m;
scanf("%d%d", &n, &m);
for(int i=0; i<m; i++){
int a, b;
scanf("%d%d", &a, &b);
g[a][b] = g[b][a] = 1;
}
//对这个图有边的不加边,没边的加边,然后用并查集分类
for(int i=1; i<=n; i++){
for(int j=i+1; j<=n; j++){
if(g[i][j] == 0){
//cout<<i<<" "<<j<<endl;
pre[f(j)] = f(i);
}
}
}
//只需要判定并查集中连通的点,是不是在原图中都不连通
int flag = 1;
for(int i=1; i<=n && flag; i++)
for(int j=i+1; j<=n && flag; j++){
int ri = f(i), rj = f(j);
if(ri == rj && g[i][j]==1){
//cout<<i<<" "<<j<<endl;
flag = 0;
}
}
if(flag)
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
}
return 0;
}
- 找到不合格的物品数量,对不合格的物品定义为存在一个其他的物品,a,b,c属性均大于他。题目数据挺水的,直接按照a,b,c三个关键字排序,然后顺序枚举,倒序判定就能过了,这样的算法复杂度在极端的情况下是O(n^2)。所以其实可以顺序枚举,然后排序之后,二分判定,这样就可以到达O(nlogn),笔试的时候就写了暴力的就过了。
代码:
#include<iostream>
#include<fstream>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdio.h>
#include<utility>
#include<algorithm>
#include<map>
#include<stack>
#include<set>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn = 500005;
const int mod = 1e9+7;
const int INF = 1<<30;
int n;
struct node
{
int a, b, c;
bool operator<(const node& n)const
{
if(a != n.a)
return a<n.a;
if(b != n.b)
return b<n.b;
return c<n.c;
}
}in[maxn];
int main( ){
//freopen("input.txt", "r", stdin);
int n;
scanf("%d", &n);
for(int i=0; i<n; i++){
scanf("%d%d%d", &in[i].a, &in[i].b, &in[i].c);
}
sort(in, in+n);
int ans = 0;
for(int i=0; i<n; i++){
for(int j=n-1; j>i; j--)
{
if(in[j].b>in[i].b && in[j].c>in[i].c)
{
ans++;
break;
}
}
}
cout<<ans<<endl;
return 0;
}