24h購物| | PChome| 登入
2013-05-14 09:59:59| 人氣1,171| 回應0 | 上一篇 | 下一篇

[UVA][二分答案+二分匹配] 11262 - Weird Fence

推薦 0 收藏 0 轉貼0 訂閱站台

Problem C
Weird Fence
Input: Standard Input

Output: Standard Output

 

In the land of our great Sultan, the World Weird Fence (WWF) festival is going to take place again. For the festival, some poles are set up in a Cartesian plane. Each pole is colored in either red or blue color. You can connect two poles with a chain that consists of multi-colored rings thus creating a weird fence. Each pole has a single hook so you can not connect more than one chain to a pole. Now, though you have an unlimited supply of chains all having the same length, it’s important to note that each of the chains has a red ring at one end & a blue ring at the other end and you are only allowed to hook up a ring to a pole with same color. Also, it’s obvious that you can use a chain to connect two poles if & only if the chain’s length is greater than or equal to the linear distance of those two poles.

 

 

Given the co-ordinates of the poles & a positive integer k, write a program to find the minimum possible integer length for the chains so that at least k weird fences can be made. The fences may cross each other.

 

Input

 

The first line of the input file is the number of test cases N. This line will be followed by a blank line. N test cases follow. First line of each test case contains two positive integers P & k where P is the number of poles on the plane. (1<=P,k<=100). Each of the next P lines has two integers X & Y & the word “red” / “blue”. X & Y are the co-ordinates of the pole (-1000<=X,Y<=1000) & the word is the color of that pole. No two poles will be in the same location. There will be a blank line between test cases.

 

Output

 

For each test case output a single integer in a line which is the minimum integer length of the chains that is necessary to make at least k fences. If it is not possible to build k fences with the given constraints, print the word “Impossible” in a single line.

 

 

 

 

 

 

Sample Input

Sample Output

2

 

6 2

-3 5 blue

-3 3 red

1 5 blue

2 0 red

4 6 blue

4 -1 red

 

6 4

-3 5 blue

-3 3 red

1 5 blue

2 0 red

4 6 blue

4 -1 red

 

6

Impossible

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


Problemsetter: Mohammad Mahmudur Rahman

Special thanks To: Manzurur Rahman Khan

題目要求的很特別,直線的歐基里得距離 (Euclidean distance),卻只要找到 integer 的距離,
使之至少 K 對匹配。

直接拉二分圖,然後二分整數距離,每二分一次就建一次圖進行匹配。

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <queue>
using namespace std;
struct Node {
    int x, y, v;// x->y, v
    int next;
} edge[30005];
int e, head[105], dis[105], prev[105], record[105];
void addEdge(int x, int y, int v) {
    edge[e].x = x, edge[e].y = y, edge[e].v = v;
    edge[e].next = head[x], head[x] = e++;
    edge[e].x = y, edge[e].y = x, edge[e].v = 0;
    edge[e].next = head[y], head[y] = e++;
}
int maxflow(int s, int t) {
    int flow = 0;
    int i, j, x, y;
    while(1) {
        memset(dis, 0, sizeof(dis));
        dis[s] =  0xffff; // oo
        queue<int> Q;
        Q.push(s);
        while(!Q.empty()) {
            x = Q.front();
            Q.pop();
            for(i = head[x]; i != -1; i = edge[i].next) {
                y = edge[i].y;
                if(dis[y] == 0 && edge[i].v > 0) {
                    prev[y] = x, record[y] = i;
                    dis[y] = min(dis[x], edge[i].v);
                    Q.push(y);
                }
            }
            if(dis[t])  break;
        }
        if(dis[t] == 0) break;
        flow += dis[t];
        for(x = t; x != s; x = prev[x]) {
            int ri = record[x];
            edge[ri].v -= dis[t];
            edge[ri^1].v += dis[t];
        }
    }
    return flow;
}
struct arc {
    int x, y, v;
    bool operator<(const arc& a) const {
        return v < a.v;
    }
};
int main() {
    int testcase;
    int N, K;
    int i, j, k;
    char s[50];
    arc D[10005];
    int A[10005], Aidx;
    scanf("%d", &testcase);
    while(testcase--) {
        scanf("%d %d", &N, &K);
        int X[105][2], Y[105][2];
        int nx = 0, ny = 0;
        for(i = 0; i < N; i++) {
            int x, y;
            scanf("%d %d %s", &x, &y, s);
            if(!strcmp(s, "blue")) {
                X[nx][0] = x;
                X[nx][1] = y;
                nx++;
            } else {
                Y[ny][0] = x;
                Y[ny][1] = y;
                ny++;
            }
        }
        int n = 0;
        for(i = 0; i < nx; i++) {
            for(j = 0; j < ny; j++) {
                D[n].x = i+1, D[n].y = nx+j+1;
                D[n].v = (X[i][0]-Y[j][0])*(X[i][0]-Y[j][0])+(X[i][1]-Y[j][1])*(X[i][1]-Y[j][1]);
                int vv = (int)sqrt(D[n].v);
                while(vv*vv < D[n].v)   vv++;
                D[n].v = vv;
                n++;
            }
        }
        sort(D, D+n);
        A[Aidx = 0] = D[0].v;
        for(i = 1; i < n; i++)
            if(D[i].v != A[Aidx])
                A[++Aidx] = D[i].v;
        int l = 0, r = Aidx, mid;
        int ret = 0xfffffff;
        while(l < r) {
            mid = (l+r)/2;
            e = 0;
            memset(head, -1, sizeof(head));
            for(i = 0; i < n && D[i].v <= A[mid]; i++)
                addEdge(D[i].x, D[i].y, 1);
            for(i = 0; i < nx; i++)
                addEdge(0, i+1, 1);
            for(i = 0; i < ny; i++)
                addEdge(nx+i+1, nx+ny+1, 1);
            int flow = maxflow(0, nx+ny+1);
            if(flow >= K)
                r = mid, ret = min(ret, A[mid]);
            else
                l = mid+1;
        }
        if(ret != 0xfffffff)
            printf("%d\n", ret);
        else
            puts("Impossible");
    }
    return 0;
}
/*
2
6 2
-3 5 blue
-3 3 red
1 5 blue
2 0 red
4 6 blue
4 -1 red
*/

台長: Morris
人氣(1,171) | 回應(0)| 推薦 (0)| 收藏 (0)| 轉寄
全站分類: 不分類 | 個人分類: UVA |
此分類下一篇:[UVA][數學] 1363 - Joseph's Problem
此分類上一篇:[UVA][二分] 11646 - Athletics Track

是 (若未登入"個人新聞台帳號"則看不到回覆唷!)
* 請輸入識別碼:
請輸入圖片中算式的結果(可能為0) 
(有*為必填)
TOP
詳全文