USACO 1.3 - Wormholes(暴力图论)

Farmer John's hobby of conducting high-energy physics experimentson weekends has backfired, causing N wormholes (2 <= N <= 12, Neven) to materialize on his farm, each located at a distinct pointon the 2D map of his farm (the x,y coordinates are both integers).

According to his calculations, Farmer John knows that his wormholeswill form N/2 connected pairs. For example, if wormholes A and Bare connected as a pair, then any object entering wormhole A willexit wormhole B moving in the same direction, and any object enteringwormhole B will similarly exit from wormhole A moving in the samedirection. This can have rather unpleasant consequences.

For example, suppose there are two paired wormholes A at (1,1)and B at (3,1), and that Bessie the cow starts from position (2,1)moving in the +x direction. Bessie will enter wormhole B [at (3,1)],exit from A [at (1,1)], then enter B again, and so on, gettingtrapped in an infinite cycle!

   | . . . .
   | A > B .      Bessie will travel to B then
   + . . . .      A then across to B again

Farmer John knows the exact location of each wormhole on hisfarm. He knows that Bessie the cow always walks in the +x direction,although he does not remember where Bessie is currently located.

Please help Farmer John count the number of distinct pairingsof the wormholes such that Bessie could possibly get trapped in aninfinite cycle if she starts from an unlucky position. FJ doesn'tknow which wormhole pairs with any other wormhole, so find all thepossibilities.

PROGRAM NAME: wormhole

INPUT FORMAT:

Line 1:The number of wormholes, N.
Lines 2..1+N:Each line contains two space-separatedintegers describing the (x,y) coordinates of a single wormhole.Each coordinate is in the range 0..1,000,000,000.

SAMPLE INPUT (file wormhole.in):
4
0 0
1 0
1 1
0 1

INPUT DETAILS:

There are 4 wormholes, forming the corners of a square.

OUTPUT FORMAT:

Line 1:The number of distinct pairings of wormholessuch that Bessie could conceivably get stuck in a cycle walkingfrom some starting point in the +x direction.

SAMPLE OUTPUT (file wormhole.out):

2

                                              

题意:

给出N个虫洞的坐标,竖直的虫洞不能相连,求出使所有虫洞相连的方案数。

思路:

本题分为3步:

1.将虫洞坐标按照x 和y 从小到大排列,将y 相同 的 相邻的点连线,具体操作是使用数组m 记录。

2. dfs 求出所有点连连相连的方案。

3.判环,看每一个方案是否能够形成环。

由于很少接触到图论的题目,所以即使知道思路却不知道怎么写,代码磨了很久>.<

CODE:

/*
ID: sotifis3
LANG: C++
TASK: wormhole
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

int N;
struct node
{
    int x, y, id;
}hole[15];
int v[15], p[15], m[15][15], ans;
bool mark[15];

bool cmp(node a, node b)
{
    if(a.y == b.y) return a.x < b.x;
    return a.y < b.y;
}
void build_maze()
{
    int fy = hole[0].y;
    int fid = hole[0].id;
    for(int i = 1; i < N; ++i){
        if(fy == hole[i].y) m[fid][hole[i].id] = 1;
        fy = hole[i].y;
        fid = hole[i].id;
    }
}
bool get_ro(int s)
{
    memset(mark, 0, sizeof(mark));
    while(1){
        if(mark[s]) return true; // 回到原点则构成圈。
        mark[s] = true;
        bool ok = false;
        for(int i = 0; i < N; ++i){
            if(m[s][i]){
                s = p[i];
                ok = true;
                break;
            }
        }
        if(!ok) return false;
    }
    return false;
}
void dfs(int n)
{
    if(n == N/2){
        for(int i = 0; i < N; ++i){
            if(get_ro(i)){
                ans++;
                break;
            }
        }
        return;
    }
    for(int i = n; i < N; ++i){
        if(!v[i]){
            v[i] = 1;
            for(int j = i + 1; j < N; ++j){
                if(!v[j]){
                    p[i] = j; p[j] = i;
                    v[j] = 1;
                    dfs(n + 1);
                    v[j] = 0;
                }
            }
            v[i] = 0;
            break;
        }
    }
}

int main()
{
    //freopen("in", "r", stdin);
    freopen("wormhole.in","r",stdin);
    freopen("wormhole.out","w",stdout);
    memset(v, 0, sizeof(v));
    memset(m, 0, sizeof(m));
    scanf("%d", &N);

    for(int i = 0; i < N; ++i){
        scanf("%d %d", &hole[i].x, &hole[i].y);
        hole[i].id = i;
    }
    sort(hole, hole + N, cmp);
    ans = 0;

    build_maze();
    dfs(0);

    printf("%d\n", ans);
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值