备孕百度之星-9月19日

记了一下prime、kruskal模板,学了并查集

prinme(力扣 1584)

class Solution {
public:
    int minCostConnectPoints(vector<vector<int>>& points) {
        //来背prime板子喽
        int n = points.size();
        int g[1005][1005], dis[1005], vis[1005];
        for(int i = 0; i < points.size(); i++)
            for(int j = 0; j < points.size(); j++)
                g[i][j] = abs(points[i][0] - points[j][0]) + abs(points[i][1] - points[j][1]);
        memset(dis, 0x3f, sizeof(dis));
        memset(vis, 0, sizeof(vis));
        int res = 0;
        for(int i = 0; i < points.size(); i++){//选n个点
            int t = -1;
            for(int j = 0; j < n; j++)
                if(!vis[j] && (t == -1 || dis[t] > dis[j])) t = j;
            if(i != 0) res += dis[t];
            vis[t] = 1;
            for(int j = 0; j < n; j++)  
                if(!vis[j]) dis[j] = min(dis[j], g[t][j]);
        }
        return res;
    }
};

kruskal(poj 1287)

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;
const int N = 10005;

struct node {
	int x, y, z;
	bool operator<(node &t)const{
		return z < t.z;
	}
}edge[N];


int fu[N];

int Find(int x){
	if(x == fu[x]) return x;
	return fu[x] = Find(fu[x]);
}

int main(){
	int n, m;
	while(cin >> n, n){
		cin >> m;
		for(int i = 1; i <= m; i++)
    		scanf("%d%d%d",&edge[i].x,&edge[i].y,&edge[i].z);
		sort(edge+1, edge+1+m);
		for(int i = 1; i <= n; i++) fu[i] = i;
		int ans = 0;
		for(int i = 0; i <= m; i++){
			int x = Find(edge[i].x);
			int y = Find(edge[i].y);
			if(x == y) continue;
			fu[x] = y;
			ans += edge[i].z;
		}
		printf("%d\n", ans);
	}	
} 


二者选择的区别在于图是稠密还是稀疏

并查集(NOI2015/洛谷R125165595)

#include<iostream>
#include<cstring>
#include<algorithm>
#include<unordered_map>

using namespace std;
typedef long long ll;
const int N = 1000005;
int fa[N];
ll ii[N], jj[N];


int Find(int x){
	if(fa[x] == x) return x;
	return fa[x] = Find(fa[x]);	
}

int main(){
	int n, T;
	cin >> T;
	while(T-- > 0){
		cin >> n;
		for(int i = 1; i <= n; i++) fa[i] = i;
//		memset(ii, 0, sizeof(ii));
//		memset(jj, 0, sizeof(jj));
		unordered_map<ll, int> map;
		int ind = 1;//第一个ll用1 
		int index = 0;
		
		string res = "YES";
		for(int i = 0; i < n; i++){
			ll x,y,e;
			cin >> x >> y >> e;
			if(e == 0){//验证 
				ii[index] = x;
				jj[index++] = y;
			}else{//并查集 
				if(map.find(x) == map.end()) map[x] = ind++;
				if(map.find(y) == map.end()) map[y] = ind++;
				int i_ind = map[x];
				int j_ind = map[y];
				fa[Find(i_ind)] = Find(j_ind);//并 
			}
		}
		for(int i = 0; i < index; i++){
			if(ii[i] == jj[i]) {
				res = "NO";
				break;
			}
			if(map.find(ii[i]) != map.end() && map.find(jj[i]) != map.end() && Find(map[ii[i]]) == Find(map[jj[i]])){
				res = "NO";
				break;
			}
		}
		cout << res << endl;
	}
}
 

被N的范围卡了40min,0的个数数错了

c++的优先队列(poj1456)

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>

using namespace std;
typedef long long ll;

struct fuc{
	bool operator()(pair<int, int> p1, pair<int, int> p2){
		return p1.first > p2.first;
	}
}; 

bool cmp(pair<int, int> a, pair<int, int> b){
	return a.second < b.second;
}

int main(){
	int n;
	while(cin >> n){
		int cur = 0;
		long res = 0;
		vector<pair<int, int> > v;
		for(int i = 0; i < n; i++){
			int x, y;
			cin >> x >> y;
			v.push_back({x, y});
		}
		
		sort(v.begin(), v.end(), cmp);
		priority_queue<pair<int, int>, vector<pair<int, int> >, fuc> q;
		for(int i = 0; i < v.size(); i++){
			if(q.size() < v[i].second){
				q.push(v[i]);
				res += v[i].first;
			}else{
				if(q.top().first < v[i].first){
					res -= q.top().first;
					q.pop();
					q.push(v[i]);
					res += v[i].first;
				}
			}
		}

		cout << res << endl;
	}
	
}
 

重点学一下比较器的写法。 无意间发现,poj的c++竟然不支持unordered_map的头文件。G++的提交不能出现错误的>>。 也就是vector<pair<int, int>> 这样写是不对的,要在>>中间加空格。

再来复习STL

一些函数:
计算公约数cout << __gcd(12,44) << endl;
统计二进制中存在几个1
cout << __builtin_popcountll(21);
定义类型名称
typedef long long ll;
初始化数组内容全是0:
int a[10];
memset(a, 0, sizeof(a))
因为memeset按字节进行赋值,所以不能赋值其他整数(字符可以通用)
计算vector的数组和:
accumulate(ans.begin(),ans.end(), 0ll);
双端队列的使用:

deque<TreeNode*> q;
q.push_front(t);
q.push_back(t);
q.pop_front();
q.pop_back();
q.size();
q.empty();
数字转字符串:
to_string(val)
字符转数字:
char - '0'
unordered_set的使用:
unordered_set<int> s;
s.insert(1);//插入
s.erase(1);//清除
s.find(1);//查找,会返回指针,判断指针是不是end()
s.find(1) == s.end() ? 不存在 : 存在
s.size();//集合大小

unordered_map的使用:
unordered_map<int, string> mp;/*insert插入*/
//1:借助pair构造函数
pair<int, string> kv(1, "one");
mp.insert(kv);
//2:借助pair构造匿名对象插入
mp.insert(pair<int, string>(2, "two"));
//3:调用make_pair函数模板插入
mp.insert(make_pair(3, "three"));
//4:使用[]运算符重载函数进行插入
mp[4] = "four";
//4:使用{}
mp.insert({ 5, "five" });

//2:范围forfor (auto e : mp)
{
cout << e.first << ":" << e.second << " ";
}
erase函数可以传入指针或者值。
比较器:(类似java,都是传一个函数)

数组:
sort(a,a+n,cmp);bool cmp(int a, int b){
return num1[a] == num1[b] ?num2[a] < num2[b] : num1[a] < num1[b];
}
vector:
vector<vector<int>> b;
sort(b.begin(), b.end(), cmp);
bool cmp(vector<int> a, vector<int> b){
return a[0] - b[0];
}

运算符优先级:
'=='  大于  '&'优先队列:

priority_queue<int> q;
q.empty();
q.push(0);
q.top();
q.pop();//返回数值

vector<vector<int>> g(numCourses);//这样使用要提前分配好空间
long long类型的绝对值:
使用llabs(ll a);

可以直接用{a,b}构造一个vector<int>
结构体的比较器:
例如kurskal的边:
struct node{
int x, y, z;
bool operator<(const node &t) const{
return z < t.z;
}
}
priority_queue重写比较器:
struct fuc{bool operator()(pair<int, int> p1, pair<int, int> p2){
return p1.first > p2.first;
}
};
priority_queue<pair<int, int>, vector<pair<int, int> > ,fuc> q;
bitset的使用:

bitset<100> s;//其实还是可以看成是一个数字cout << s[5] << endl;
s.set();
s >>= 10;
cout << s[5] << endl;
unique去重函数:
vector<int> a;
int m = unique(a.begin(), a.end()) - a.begin();//返回去重后的个数

二分查找:
lower_bound(a, a+n, x);//找大于等于x的数
upper_bound(a, a+n, x);//找小于等于x的数



全部评论

相关推荐

尊嘟假嘟点击就送:加v细说,问题很大
点赞 评论 收藏
分享
我是小红是我:学校换成中南
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务