POJ 2263 POJ 1556

2263 题目意思是求起点城市到终点城市的途径中的最大载重量,可以用Dijkstra或者floyd 来解决,我是用的floyd 感觉更直观 因为只需要将递推式改成w[i][j] = Max(w[i][j],Min(w[i][k],w[k][j]));便可得到答案,而且floyd写法比较简单但是复杂度为n的3次方,不过此题还是能AC

Source Code
Problem: 2263        User: lyz963254
Memory: 760K        Time: 32MS
Language: G++        Result: Accepted

    Source Code

    #include <iostream>
    #include <cstdio>
    #include <cstring>

    using namespace std;

    int Max(int x,int y)
    {
        return x>y?x:y;
    }
    int Min(int x,int y)
    {
        return x<y?x:y;
    }

    const int M = 250;

    int kase = 0;
    int n,r;
    int num;
    int w[M][M];

    char city[M][35];
    char start[35],dest[35];

    int index(char *s)
    {
        int i;
        for(i=0;i<num;i++){
            if(!strcmp(city[i],s)) return i;
        }
        strcpy(city[i],s);
        num++;
        return i;
    }

    int read()
    {
        int i,j,k,limit;
        scanf("%d%d",&n,&r);
        if(n==0) return 0;
        for(i=0;i<n;i++){
            for(j=0;j<n;j++)
                    w[i][j] = 0;
                w[i][i] = 9999999;
            }
            num = 0;
            for(k=0;k<r;k++){
                scanf("%s%s%d",start,dest,&limit);
                i = index(start);
                j = index(dest);
                w[i][j] = w[j][i] = limit;
            }
            scanf("%s%s",start,dest);
            return 1;
    }
    void solve()
    {
        int i,j,k;
        for(k=0;k<n;k++){
            for(i=0;i<n;i++){
                for(j=0;j<n;j++){
                    w[i][j] = Max(w[i][j],Min(w[i][k],w[k][j]));
                }
            }
        }
        i = index(start);
        j = index(dest);
        printf("Scenario #%d\n%d tons\n\n",++kase,w[i][j]);
    }
    int main ()
    {
        while(read()){
            solve();
        }
        return 0;
    }

1556 简直建图建醉了,算法直接套用bellman-ford 但是建图的过程太恶心了,需要判断墙的是否阻断了a,b顶点,阻断则不连边否则连边。。。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>

using namespace std;

#define inf 20000000000
#define M 150

struct Point
{
    double x;
    double y;
}p[M];

struct edge
{
    int u;
    int v;
}e[10050];

int n;//房间的数目
int pSize; //点的数目
double wX[20];//墙的X坐标
double pY[20][4];//Y的坐标
double map[M][M];//邻接矩阵
int eSize; //边的数目
int i,j;

double Dis(Point a,Point b)
{
    return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
}

double Cross(double x1,double y1,double x2,double y2,double x3,double y3) //判断点是否在直线的上方还是下方
{
    return (x2-x1)*(y3-y1) - (x3-x1)*(y2-y1);
}
bool Ok(Point a,Point b) //判断在构造有向网的时候两点能否连边
{
    if(a.x>=b.x) return false;
    bool flag = true;
    int i = 0;
    while(wX[i]<=a.x&&i<n){
        i++;
    }
    while(wX[i]<b.x&&i<n){
        if(Cross(a.x,a.y,b.x,b.y,wX[i],0)*Cross(a.x,a.y,b.x,b.y,wX[i],pY[i][0])<0
           ||
           Cross(a.x,a.y,b.x,b.y,wX[i],pY[i][1])*Cross(a.x,a.y,b.x,b.y,wX[i],pY[i][2])<0
           ||
           Cross(a.x,a.y,b.x,b.y,wX[i],pY[i][3])*Cross(a.x,a.y,b.x,b.y,wX[i],10)<0){
            flag = false;
            break;
           }
           i++;
    }
    return flag;
}
double bellman(int beg,int end)
{
    double dist[M];
    int i,j;
    for(i=0;i<M;i++){
        dist[i] = inf;
    }
    dist[beg] = 0;
    bool ex = true;
    for(i=0;i<pSize&&ex;i++){
            ex = false;
            for(j=0;j<eSize;j++){
                if(dist[e[j].u]<inf&&(dist[e[j].v]>(dist[e[j].u]+map[e[j].u][e[j].v]))){
                    dist[e[j].v] = dist[e[j].u]+map[e[j].u][e[j].v];
                    ex = true;
            }
        }
    }
    return dist[end];
}

void solve()
{
    p[0].x = 0;
    p[0].y = 5;
    pSize = 1;
    for(i=0;i<n;i++){
        scanf("%lf",&wX[i]);
        for(j=0;j<4;j++){
            p[pSize].x = wX[i];
            scanf("%lf",&p[pSize].y);
            pY[i][j] = p[pSize].y;
            pSize++;
        }
    }
    p[pSize].x=10;
    p[pSize].y=5;

    pSize++;
    for(i=0;i<pSize;i++){
            for(j=0;j<pSize;j++){
                map[i][j] = inf;
            }
    }
    eSize = 0;
    for(i=0;i<pSize;i++){
        for(j=i+1;j<pSize;j++){
            if(Ok(p[i],p[j])){
                map[i][j] = Dis(p[i],p[j]);
                e[eSize].u = i;
                e[eSize].v = j;
                eSize++;
            }
        }
    }
    printf("%.2lf\n",bellman(0,pSize-1));

}

int main ()
{
    while(scanf("%d",&n)!=EOF){
        if(n==-1) break;
        solve();
    }
    return 0;
}

时间: 2024-10-03 15:01:31

POJ 2263 POJ 1556的相关文章

poj 2263

群 #include <iostream>#include <cstdio>#include <string>#include <cstring>#include <algorithm>using namespace std;#include <map>int a[205][205];int main(int argc, char *argv[]){ int m,n,i,j,k,r,p=0; string s1,s2; while(c

POJ 2263 Heavy Cargo(二分+并查集)

题目地址:POJ 2263 这题是在网上的一篇关于优先队列的博文中看到的..但是实在没看出跟优先队列有什么关系..我用的二分+并查集做出来了... 二分路的载重量.然后用并查集检查是否连通. 代码如下: #include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <ctype.h> #

Poj 2263 Heavy Cargo Floyd 求最大容量路

f[i][j] = max(f[i][j],min(f[i][k],f[j][k])) #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cst

poj 3903 &amp; poj 2533 最长上升子序列(LIS)

最长上升子序列. 做这道题之前先做了2533,再看这道题,感觉两道题就一模一样,于是用2533的代码直接交, TLE了: 回头一看,数据范围.2533 N:0~1000:3903 N :1~100000. 原因终归于算法时间复杂度. 也借这道题学习了nlgn的最长上升子序列.(学习链接:http://blog.csdn.net/dangwenliang/article/details/5728363) 下面简单介绍n^2 和 nlgn 的两种算法. n^2: 主要思想:DP: 假设A1,A2..

半平面交 模板 poj 3335 poj 3130 poj 1474 判断半平面交是否为空集

半平面交模板 const double pi= acos(-1.0); #define arc(x) (x / 180 * pi) const double EPS = 1e-8; const int Max_N = 105; struct Point{ double x,y; Point(){} Point(double x, double y):x(x),y(y){} Point operator - (Point p){ return Point(x- p.x , y - p.y ) ;

POJ 3670 &amp;&amp; POJ 3671 (dp)

最长不下降子序列的应用嘛.两题都是一样的. POJ 3670:求给定序列按递增或递减排列时,所需改变的最小的数字的数目. POJ 3671:求给定序列按递增排列时,所需改变的最小的数字的数目. 思路就是求最长不下降子序列,然后剩下的就是需要改变的字母. 最长不下降子序列:(我之前有写过,不懂请戳)http://blog.csdn.net/darwin_/article/details/38360997 POJ 3670: #include<cstdio> #include<cstring

poj 3090 &amp;&amp; poj 2478(法雷级数,欧拉函数)

http://poj.org/problem?id=3090 法雷级数 法雷级数的递推公式很简单:f[1] = 2; f[i] = f[i-1]+phi[i]. 该题是法雷级数的变形吧,答案是2*f[i]-1. #include <stdio.h> #include <iostream> #include <map> #include <set> #include <stack> #include <vector> #include

二分图匹配 最大匹配数+最大点覆盖 POJ 1469+POJ 3041

最大匹配数就等于最大点覆盖,因为在图里面,凡是要覆盖的点必定是连通的,而最大匹配之后,若还有点没有覆盖到,则必定有新的匹配,与最大匹配数矛盾,如果去掉一些匹配,则必定有点没有覆盖到. POJ 1469 比较简单,用的经典的二分图匹配算法. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46

POJ 1496 POJ 1850 组合计数

Code Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 8256 Accepted: 3906 Description Transmitting and memorizing information is a task that requires different coding systems for the best use of the available space. A well known system is t