uva10048 (floyd & kruskal)

题目大意:
给出两点和他们之间的噪音值,找出从起点到终点的一条路,使得这条路中噪音最大的是所有路径中最小的。

思路:
floyd算法:
找出一条路中噪音最大的
例如i和j之间噪音最大值是:
d[i][j] = min(d[i][j],max(d[i][k],d[k][j]));
即可能是i直接到j的噪音最大或者i到j的路途中某一段的噪音最大

kruskal算法:
由于该算法是按照权值一个一个并入生成树中的,所以当并入一个权值之后出现了从起点到终点的路径的时候,那么该权值就是要求的权值,因为权值是从小到大并入的。

代码:
floyd:

#include 
using namespace std;
#include 
#include 
const int N = 105;
const int INF = 0x3f3f3f3f;
int d[N][N],n,m,Q;

void Floyd() {
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++)
            for(int k = 1; k <= n; k++) {
                d[j][k] = min(d[j][k],max(d[j][i],d[i][k]));
            }
}
void output() {
    int u,v;
    for(int i = 0; i < Q;i++) {
        scanf("%d %d",&u,&v);
        if(d[u][v] != INF)
            printf("%d\n",d[u][v]);
        else 
            printf("no path\n");
    }
}
int main() {

    int T = 0;
    while(scanf("%d %d %d",&n,&m,&Q) && m && n &&Q)  {
        for(int i = 1; i < N; i++) {
            d[i][i] = INF;
            for(int j = i + 1; j < N; j++)
                d[i][j] = d[j][i] = INF;
        }
        int a,b,c;
        for(int i = 0; i < m; i++) {
            scanf("%d %d %d",&a,&b,&c);
            d[a][b] = d[b][a] = c;
        }
        Floyd();
        if(T)
            printf("\n");
        printf("Case #%d\n",++T);
        output();
    }
    return 0;
}

kruskal:

#include 
using namespace std;
#include 
#include 
#include 

const int N = 105;
int map[N][N];
int n,m,q;
int father[N];

struct node {
    int a,b,c;
}e[N * N];
int cmp(const node & a,const node &b) {
    return a.c < b.c;
}
int find(int x) {
    int i,j,k = x;
    while(k != father[k]) {
        k = father[k];
    }
    i = x;
    while(i != k) {
         j = father[i];
         father[i] = k;
         i = j;
    }
    return k;
}

void Union(int x,int y) {
    int xx = find(x);
    int yy = find(y);
    if(xx < yy)
        father[xx] = yy;
    else
        father[yy] = xx;
}
int main() {
    int T = 0;
    int x,y;
    while(scanf("%d %d %d",&n,&m,&q) && n && m && q) {
        for(int i = 1; i <= m; i++)
            scanf("%d %d %d",&e[i].a,&e[i].b,&e[i].c);
        sort(e + 1, e + 1 + m,cmp);
        if(T)
            printf("\n");
        printf("Case #%d\n",++T);
        for(int i = 1; i <= q; i++) {
            scanf("%d %d",&x,&y);
            int j;
            for(j = 1; j <= n; j++)
                father[j] = j;
            for(j = 1; j <= m; j++) {
                Union(e[j].a,e[j].b);
                if(find(x) == find(y))
                    break;
            }
            if(j > m)
                printf("no path\n");
            else
                printf("%d\n",e[j].c);
        }
    }
    return 0;
}

你可能感兴趣的:(图,kruckal算法,floyd算法)