一部分链前代码
to:当前节点所连接的下一个节点
nxt:当前节点所连的下一条边
head:当前节点所连接的第一个边
还不是很理解,先把板子写好,慢慢在看把
1 #include <cstdio> 3 #include <iostream> 4 using namespace std; 5 int const N=1e4; 6 int cnt,head[N],to[N],nxt[N]; 7 void addedge(int u,int v) 8 { 9 nxt[++cnt]=head[u]; 10 to[cnt]=v; 11 head[u]=cnt; 12 return; 13 } 14 int st,ed; 15 for (int i = head[st];i != 0;i = head[i]) 16 {//遍历一个点所连接的边 17 }
关于货车运输
那就先最大生成树,来确保每一条路径上最小的值最大。邻接表记录,dfs构建树,LCA查找,害,可以说是一道很复杂的较简单的题。(划重点:很复杂的!!!简单(弱弱的)题)
题目描述
A 国有 n 座城市,编号从 1 到 n ,城市之间有 m 条双向道路。每一条道路对车辆都有重量限制,简称限重。
现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物。
输入格式
第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道路。
接下来 m 行每行三个整数 x,y,z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y 号城市有一条限重为 z 的道路。
注意: x≠y,两座城市之间可能有多条道路 。
接下来一行有一个整数 q,表示有 q 辆货车需要运货。
接下来 q 行,每行两个整数 x,y,之间用一个空格隔开,表示一辆货车需要从 x城市运输货物到 y 城市,保证 x≠y
输出格式
共有 q 行,每行一个整数,表示对于每一辆货车,它的最大载重是多少。
如果货车不能到达目的地,输出 −1。
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <algorithm> 5 #include <iostream> 6 #include <vector> 7 #include <map> 8 #include <set> 9 #include <queue> 10 #include <cstdlib> 11 #include <ctime> 12 using namespace std; 13 const int maxn = 1e5 + 10; 14 int n,m; 15 // 邻接表 16 struct edge_ljb{ 17 int nextId; 18 int dist; 19 }; 20 vector <edge_ljb> node[maxn]; 21 // 存储边信息 22 struct edge{ 23 int a,b,dist; 24 }; 25 vector <edge> edges; 26 bool cmp (const edge &a, const edge &b){ 27 return a.dist > b.dist; 28 } 29 //并查集 30 int fa[maxn]; 31 void inits(int n){ 32 for (int i = 0 ;i<= n ;i++){ 33 fa[i] = i; 34 } 35 } 36 int Find(int v){ 37 if (v == fa[v]) 38 return v; 39 fa[v] = Find(fa[v]); 40 return fa[v]; 41 } 42 void update(int u, int v){ 43 int fu = Find(u); 44 int fv = Find(v); 45 fa[fu] = fv; 46 } 47 //公共祖先节点信息 48 int deps[maxn]; 49 int faId[maxn],faDist[maxn]; 50 void calNodedeps(int u, int fa){ 51 for (unsigned int i = 0 ;i< node[u].size() ;i++){ 52 int nextId = node[u][i].nextId; 53 if (nextId != fa){ 54 deps[nextId] = deps[u] + 1; 55 faId[nextId] = u; 56 faDist[nextId] = node[u][i].dist; 57 calNodedeps(nextId,u); 58 } 59 } 60 } 61 int LCA(int u, int v){ 62 int ans = 1000000000; 63 while (u!=v){ 64 if (deps[u] == deps[v]) { 65 ans = min(ans, faDist[u]); 66 ans = min(ans, faDist[v]); 67 u = faId[u]; 68 v = faId[v]; 69 continue; 70 } 71 if (deps[u] < deps[v]) swap(u,v); 72 ans = min(ans, faDist[u]); 73 u = faId[u]; 74 } 75 return ans; 76 } 77 int main (){ 78 while (~scanf("%d%d",&n,&m)){ 79 edges.clear(); 80 for (int i = 0 ;i< m ;i++){ 81 edge tmp; 82 scanf("%d%d%d",&tmp.a,&tmp.b,&tmp.dist); 83 edges.push_back(tmp); 84 } 85 //最大生成树 86 sort(edges.begin(),edges.end(),cmp); 87 inits(n); 88 for (int i = 0 ;i<= n ;i++) 89 node[i].clear(); 90 for (int i = 0 ;i< m;i++){ 91 int a = edges[i].a, b = edges[i].b; 92 if (Find(a)!= Find(b)){ 93 update(a,b); 94 edge_ljb tmp; 95 tmp.dist = edges[i].dist; 96 tmp.nextId = b; 97 node[a].push_back(tmp); 98 tmp.nextId = a; 99 node[b].push_back(tmp); 100 } 101 } 102 // 计算答案 103 memset(deps,0,sizeof deps); 104 memset(faId,-1,sizeof faId); 105 memset(faDist,0,sizeof faDist); 106 for (int i = 0; i< n ;i++){ 107 if (faId[i] == -1) 108 calNodedeps(i,-1); 109 } 110 int QNum;cin>>QNum; 111 for (int i = 0 ;i< QNum ;i++){ 112 int a,b; 113 scanf("%d%d",&a,&b); 114 if (Find(a)!= Find(b)){ 115 printf("-1\n"); 116 } 117 else { 118 printf("%d\n",LCA(a,b)); 119 } 120 } 121 } 122 return 0; 123 }