1.Freckles
#include<iostream>
#include<algorithm>
#include<cmath>
#include<iomanip>
using namespace std;
const int maxn=100;
struct Distance{
int from;
int to;
double length;
bool operator<(Distance dis){
return length<dis.length;
}
};
struct point{ //点结构
double x;
double y;
};
Distance dis[maxn*maxn];
int father[maxn];
int height[maxn];
point pt[maxn];
void Initial(int n){
for(int i=0;i<n;i++){
father[i]=i;
height[i]=0;
}
return ;
}
int find(int x){
if(x!=father[x]){
father[x]=find(father[x]);
}
return father[x];
}
void Union(int x,int y){
x=find(x);
y=find(y);
if(x!=y){
if(height[x]>height[y])
father[y]=x;
else if(height[x]<height[y])
father[x]=y;
else{
father[x]=y;
height[y]++;
}
}
return ;
}
double Kruskal(int n,int edgeNumber){
Initial(n);
sort(dis,dis+(n-1)*n/2);
double sum=0.0;
for(int i=0;i<edgeNumber;i++){
Distance current=dis[i];
if(find(current.from)!=find(current.to)){
Union(current.from,current.to);
sum+=current.length;
}
}
return sum;
}
double getDis(point p1,point p2){ //计算两个点之间的距离
return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}
int main(){
int n;
double x1,x2,y1,y2;
while(cin>>n){
if(n==0)break;
int edgeNumber=n*(n-1)/2;
for(int i=0;i<n;i++)
cin>>pt[i].x>>pt[i].y;
int num=0;
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++)
{
dis[num].from=i;
dis[num].to=j;
dis[num++].length=getDis(pt[i],pt[j]);
}
}
double answer=Kruskal(n,num+1);
cout<<setiosflags(ios::fixed)<<setprecision(2)<<answer<<endl;
}
return 0;
}
2. Jungle Roads
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=27;
struct Edge{
int from;
int to;
int length;
bool operator<(Edge e){
return length<e.length;
}
};
int father[maxn];
int height[maxn];
Edge edge[maxn*maxn];
void Initial(int n){
for(int i=0;i<n;i++){
father[i]=i;
height[i]=0;
}
}
int find(int x){
if(x!=father[x]){//路径压缩
father[x]=find(father[x]);
}
return father[x];
}
void Union(int x,int y){
x=find(x);
y=find(y);
if(x!=y){
if(height[x]>height[y])
father[y]=x;
else if(height[x]<height[y])
father[x]=y;
else {
father[x]=y;
height[y]++;
}
}
return ;
}
int Kruskal(int n,int edgeNumber){
Initial(n);
sort(edge,edge+edgeNumber);
int sum=0;
for(int i=0;i<edgeNumber;i++){
Edge current=edge[i];
if(find(current.from)!=find(current.to)){
Union(current.from,current.to);
sum+=current.length;
}
}
return sum;
}
int main(){
int n;
while(cin>>n){
if(n==0)break;
int edgeNumber=0;
for(int i=1;i<n;i++){
char c; int num;
cin>>c>>num;
for(int j=0;j<num;j++){
char temp; int dist;
cin>>temp>>dist;
edge[edgeNumber].from=i-1;
edge[edgeNumber].to=temp-'A';
edge[edgeNumber++].length=dist;
}
}
int answer=Kruskal(n,edgeNumber);
cout<<answer<<endl;
}
return 0;
}
3.畅通工程续(最短路径问题)
#include<iostream>
#include<vector>
#include<cstring>
#include<climits>
#include<queue>
using namespace std;
const int maxn=200;
const int inf=INT_MAX;
struct Edge{
int to;
int length;
Edge(int t,int l):to(t),length(l){
}
};
struct Point{
int num; //点的编号
int distance; //源点到该点的距离
Point(int n,int d):num(n),distance(d){}
bool operator<(const Point&p)const{
return distance>p.distance;
}
};
vector<Edge> graph[maxn];
int dis[maxn];
void Dijkstra(int s){
priority_queue<Point> myPQueue;
dis[s]=0;
myPQueue.push(Point(s,dis[s]));
while(!myPQueue.empty()){
int u=myPQueue.top().num;
myPQueue.pop();
for(int i=0;i<graph[u].size();i++){
int v=graph[u][i].to;
int d=graph[u][i].length;
if(dis[v]>dis[u]+d){
dis[v]=dis[u]+d;
myPQueue.push(Point(v,dis[v]));
}
}
}
return ;
}
int main(){
int n,m;
while(cin>>n>>m){
memset(graph,0,sizeof(graph));
fill(dis,dis+n,inf); //初始化距离为无穷大
while(m--){
int from,to,length;
cin>>from>>to>>length;
graph[from].push_back(Edge(to,length));
graph[to].push_back(Edge(from,length));
}
int s,t;
cin>>s>>t;
Dijkstra(s);
if(dis[t]==inf)
dis[t]=-1;
cout<<dis[t]<<endl;
}
return 0;
}
4.最短路径问题
#include<iostream>
#include<climits>
#include<algorithm>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
const int maxn=1001;
const int INF=INT_MAX;
struct Edge{
int to;
int length;
int money;
Edge(int t,int l,int m):to(t),length(l),money(m){}
};
struct Point{
int num;
int distance;
int price;
Point(int n,int d,int p):num(n),distance(d),price(p){}
bool operator<(const Point &p)const{
return distance>p.distance;
}
};
vector<Edge> graph[maxn];
int dis[maxn]; //到源点的距离
int price[maxn]; //到原点的价格
void Dijkstra(int s){
priority_queue<Point> myPQueue;
dis[s]=price[s]=0;
myPQueue.push(Point(s,dis[s],price[s]));
while(!myPQueue.empty()){
int u=myPQueue.top().num;//离源点距离最近的点
myPQueue.pop();
for(int i=0;i<graph[u].size();i++){
int v=graph[u][i].to;
int d=graph[u][i].length;
int p=graph[u][i].money;
if(dis[v]>dis[u]+d){
dis[v]=dis[u]+d;
price[v]=price[u]+p;
myPQueue.push(Point(v,dis[v],price[v]));
}
else if(dis[v]==dis[u]+d&&price[v]>price[u]+p){
dis[v]=dis[u]+d;
price[v]=price[u]+p;
myPQueue.push(Point(v,dis[v],price[v]));
}
}
}
return ;
}
int main(){
int n,m;
while(cin>>n>>m){
if(n==0)break;
memset(graph,0,sizeof(graph));
fill(dis,dis+n+1,INF);
fill(price,price+n+1,INF);
while(m--){
int from,to,length,pri;
cin>>from>>to>>length>>pri;
graph[from].push_back(Edge(to,length,pri));
graph[to].push_back(Edge(from,length,pri));
}
int s,t;
cin>>s>>t;
Dijkstra(s);
cout<<dis[t]<<" "<<price[t]<<endl;
}
return 0;
}
5.最短路径
链接:https://www.nowcoder.com/questionTerminal/a29d0b5eb46b4b90bfa22aa98cf5ff17?f=discussion
来源:牛客网
#include<stdio.h>
#define N 100
int dis[N][N];
int Tree[N];
int FindRoot(int x){
if(Tree[x]==-1) return x;
else{
Tree[x]=FindRoot(Tree[x]);
return Tree[x];
}
}
int mod(int x,int y){
int ret=1;
while(y--){
ret=(ret*x)%100000;
}
return ret;
}
int main(){
int n,m;
while(scanf("%d%d",&n,&m)!=EOF){
int i,j,k,a,b,x,y,dist;
for(i=0;i<n;i++){
Tree[i]=-1;
for(j=0;j<n;j++)
dis[i][j]=-1;
dis[i][i]=0;
}
for(i=0;i<m;i++){
scanf("%d%d",&a,&b);
x=FindRoot(a);
y=FindRoot(b);
if(x!=y){
dist=mod(2,i);
for(j=0;j<n;j++){
if(x==FindRoot(j)){
for(k=0;k<n;k++){
if(y==FindRoot(k)){
dis[j][k]=dis[k][j]=(dis[j][a]+dis[b][k]+dist)%100000;
}
}
}
}
Tree[y]=x;
}
}
x=FindRoot(0);
for(i=1;i<n;i++){
printf("%d\n",dis[0][i]);
}
}
return 0;
}