UVA 10687 (DFS)

题目说如果有多个站符合题意,就先选最西边,再选最南边。
刚开始没有太懂得他的意思,样例都懂不了,后来看了大神的代码,才明白是按x,y排序。
按照题意排序规则如下:
1.先找最接近的点。
2.如果距离相等,就先按x从小到大进行排序,再按照y从小到大排序。
对访问过的点进行标记,
从最开始的站进行搜索。返回值是搜索到的站的个数
从而判断输出结果。
由于每次到一个站都要进行排序,有点繁琐,所以采用了直接循环判断即可。
代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<map>
#include<vector>
#include<cmath>
#include<cstdlib>
#include<list>
#include<queue>
#define mm(a,b) memset(a,b,sizeof(a))
#define ACCELERATE (ios::sync_with_stdio(false),cin.tie(0))
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
#define MAXNL 0x3fffffff
#define MAXN 0x3f3f3f3f
using namespace std;

int x[1025],y[1025],vis[1025];
int n;


int dfs(int a){
    int b,c,i,k,r;
    if(a<0||vis[a]++)
        return 0;
    for(i=0,b=-1,k=0;i<n;i++){
        if(i==a) continue;
        r=(x[a]-x[i])*(x[a]-x[i])+(y[a]-y[i])*(y[a]-y[i]);
        if(b<0||k>r||(k==r&&(x[i]<x[b]||(x[i]==x[b]&&y[i]<y[b])))){
            b=i;k=r;
        }
    }
    for(i=0,c=-1,k=0;i<n;i++){
        if(i==a||i==b) continue;
        r=(x[a]-x[i])*(x[a]-x[i])+(y[a]-y[i])*(y[a]-y[i]);
        if(c<0||k>r||(k==r&&(x[i]<x[c]||(x[i]==x[c]&&y[i]<y[c])))){
            c=i;k=r;
        }
    }
    return (dfs(b)+dfs(c)+1);
}

int main()
{
//    freopen("in.txt","r",stdin);
//    freopen("out.txt","w",stdout);
    while(scanf("%d",&n)!=EOF&&n){
        mm(vis,0);
        for(int i=0;i<n;i++){
            scanf("%d%d",&x[i],&y[i]);
        }
        if(dfs(0)==n) printf("All stations are reachable.\n");
        else printf("There are stations that are unreachable.\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40679299/article/details/80711816
今日推荐