1.堆优化dijkstra
#include<bits/stdc++.h> using namespace std; //邻接表,first是邻接点编号,second是cost vector<vector<pair<int, int>>> graph; struct mycmp{ bool operator()(const pair<int, int>& p1, const pair<int, int>& p2){ return p1.second > p2.second; } }; vector<int> dijkstra(int s) { int n = graph.size(); priority_queue<pair<int, int>, vector<pair<int, int>>, mycmp> pq; vector<int> dis(n, INT_MAX); //源设置为0 dis[s] = 0; pq.emplace(s,0); while (!pq.empty()) { // auto [d, u] = pq.top(); auto minpos = pq.top(); pq.pop(); if (minpos.second> dis[minpos.first]) continue; // for (auto [v, w] : graph[minpos.second]) for (auto node : graph[minpos.first]) { if (minpos.second + node.second < dis[node.first]) { dis[node.first] = minpos.second + node.second; pq.emplace(node.first, dis[node.first]); } } } return dis; } void init(){ graph.resize(6); graph[0].push_back({1,7}); graph[0].push_back({5,3}); graph[0].push_back({2,4}); graph[1].push_back({0,7}); graph[1].push_back({5,5}); graph[1].push_back({3,9}); graph[2].push_back({0,4}); graph[2].push_back({5,6}); graph[2].push_back({4,5}); graph[3].push_back({1,9}); graph[3].push_back({5,6}); graph[3].push_back({4,2}); graph[4].push_back({3,2}); graph[4].push_back({5,1}); graph[4].push_back({2,5}); graph[5].push_back({0,3}); graph[5].push_back({1,5}); graph[5].push_back({2,6}); graph[5].push_back({3,6}); graph[5].push_back({4,1}); } int main(){ //建个节点数目为6的带权连通图 init(); int n =graph.size(); //任选一个节点开始,这里从0开始 auto dist = dijkstra(1); for(int i=0;i<n;++i){ cout<<dist[i]<<" "; } return 0; }
2.最小生成树Prim
#include<bits/stdc++.h> using namespace std; //n为点的个数 int n = 6; //给出带权图 //邻接,first为点,second为权 vector<vector<pair<int, int>>> graph(n); struct mycmp{ bool operator()(const pair<int, int>& p1, const pair<int, int>& p2){ return p1.second > p2.second; } }; priority_queue<pair<int, int>, vector<pair<int, int>>, mycmp> pq; //已查集合 set<int> vis; int ans = 0; //带权图为输入 void prim(vector<vector<pair<int, int>>>& graph, int pos){ vis.insert(pos); for(int i=0;i<graph[pos].size();++i){ pq.push(graph[pos][i]); } while(!pq.empty()){ auto nxpos = pq.top().first; auto diff = pq.top().second; pq.pop(); if(vis.count(nxpos))continue; vis.insert(nxpos); ans+=diff; if(vis.size() == graph.size())break; for(int i=0;i<graph[nxpos].size();++i){ if(vis.count(graph[nxpos][i].first))continue; pq.push(graph[nxpos][i]); } } } void init(){ graph[0].push_back({1,7}); graph[0].push_back({5,3}); graph[0].push_back({2,4}); graph[1].push_back({0,7}); graph[1].push_back({5,5}); graph[1].push_back({3,9}); graph[2].push_back({0,4}); graph[2].push_back({5,6}); graph[2].push_back({4,5}); graph[3].push_back({1,9}); graph[3].push_back({5,6}); graph[3].push_back({4,2}); graph[4].push_back({3,2}); graph[4].push_back({5,1}); graph[4].push_back({2,5}); graph[5].push_back({0,3}); graph[5].push_back({1,5}); graph[5].push_back({2,6}); graph[5].push_back({3,6}); graph[5].push_back({4,1}); } int main(){ //建个节点数目为6的带权连通图 init(); //任选一个节点开始,这里从0开始 prim(graph, 0); cout<<ans<<endl; return 0; }
3.匈牙利算法(二分图配对)
#include<bits/stdc++.h> using namespace std; //结果集合 //表示x部的和y部的匹配 int cx[200]; //同理 int cy[200]; //dfs查找一条增广 //选择一个部进行查找,match代表的是x部和y部的节点是否相连,vis是另一个部是否被标记 bool dfs(int u, vector<vector<int>>& match, set<int>& vis){ //如果选择行(x部)作为u的输入,则遍历列(y部) for(int v = 0; v< match[0].size(); ++v){ //有路径并且未被标记 if(match[u][v] && !vis.count(v)){ //标记 vis.insert(v); //如果y部的这个节点还没有匹配,那么直接加入即可,如果匹配了,递归查找是否能够替换匹配,能的话更换 if(cy[v] == -1 || dfs(cy[v], match, vis)){ cx[u] = v; cy[v] = u; return true; } } } return false; } int matchmax(vector<vector<int>>& match){ int ans = 0; //全部初始化为未匹配 memset(cx, -1, sizeof(cx)); memset(cy, -1, sizeof(cy)); //遍历行,找匹配 for(int i=0;i<match.size(); ++i){ //如果还没匹配,找匹配 if(cx[i] == -1){ set<int> vis; ans += dfs(i, match, vis); } } return ans; } int main(){ vector<vector<int>> match(4, vector<int>(4)); match[0][0] = 1; match[0][2] = 1; match[1][0] = 1; match[2][0] = 1; match[2][1] = 1; match[3][2] = 1; match[3][3] = 1; cout<<matchmax(match)<<endl; return 0; }