day1 火车运输

对于前六十分来说,运用SPFA或者DFS可以解决,其中要运用到最大生成树。代码如下:(SPFA)

#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define _min(a,b) ((a) < (b))?(a):(b)
using namespace std;
int n,m,k;
FILE *fin = fopen("truck.in","r");
FILE *fout= fopen("truck.out","w");
typedef class Edge{
public:
int next;
int end;
int z;
Edge():next(0),end(0),z(0){}
Edge(int next, int end, int z):next(next),end(end),z(z){}
}Edge;
int *h;
int *h1;
Edge *edge1;
int _now = 0;
typedef struct gdata{
int from;
int end;
}gdata;
typedef bool boolean;
gdata g;
int buffer[3];
void add(int from, int end, int v){
edge1[++_now] = Edge(h[from], end, v);
h[from] = _now;
}
typedef struct Edge1{
int from;
int end;
int v;
}Edge1;
int *fset; //并查集
int _find(int found){
if(fset[found] != found) return ( fset[found] = _find(fset[found]) );
return fset[found];
}
void unit(int &a, int &b){
int af = _find(a);
int bf = _find(b);
fset[bf] = af;
}
queue<int> que;
boolean *visited;
int *f;
Edge1 *edge;
int solve(){
memset(visited, false, sizeof(boolean) * (n + 1));
memset(f,-1, sizeof(int) * (n + 1));
if(h[g.end] == 0||h[g.from] == 0) return -1;
f[g.from] = 1000000;
visited[g.from] = true;
que.push(g.from);
while(!que.empty()){
int u = que.front();
que.pop();
visited[u] = false;
for(int i = h[u];i != 0;i = edge1[i].next){
int eu = edge1[i].end;
if(f[eu] < (_min(f[u] ,edge1[i].z))){
f[eu] = (_min(f[u] ,edge1[i].z));
if(!visited[eu]){
visited[eu] = true;
que.push(eu);
}
}
}
}
if(f[g.end] < 0) return -1;
return f[g.end];
}
boolean cmpare(const Edge1& a, const Edge1& b){
return a.v > b.v;
}
void init_myTree(){
fset = new int[(const int)(n + 1)];
sort(edge+1, edge + m * 2 + 1, cmpare);
for(int i = 1;i <= n; i++) fset[i] = i;
int _count = 0;
for(int i = 1;i <= m;i++){
if(_count == n - 1) break;
if(_find(edge[i].from) != _find(edge[i].end)){
add(edge[i].from, edge[i].end, edge[i].v);
add(edge[i].end, edge[i].from, edge[i].v);
unit(edge[i].from, edge[i].end);
_count++;
}
}
delete[] edge;
delete[] fset;
}
int main(){
fscanf(fin,"%d%d",&n,&m);
h = new int[(const int)(n + 1)];
edge = new Edge1[(const int)(m * 2 + 1)];
memset(h, 0, sizeof(int) * (n + 1));
visited = new boolean[(const int)(n + 1)];
f = new int[(const int)(n + 1)];
edge1 = new Edge[(const int)(n * 2 + 1)];
for(int i = 1;i <= m;i++){
fscanf(fin,"%d%d%d",&edge[i].from,&edge[i].end,&edge[i].v);
}
init_myTree();
fscanf(fin,"%d",&k);
for(int i = 1;i <= k;i++){
fscanf(fin,"%d%d",&g.from,&g.end);
fprintf(fout,"%d\n",solve());
}
return 0;
}

对于正解来说,贪心+最大生成树+树上倍增可解,代码还未完成~

清清正正射命丸文是也~

原文地址:https://www.cnblogs.com/Ayateriteri/p/5661723.html