absi2011's Blog & Daily Life.

全新的开始       我要省选翻盘       I wanna AK in 高考\化学       自此,生无可恋
100729 D 解题报告
100729 A 解题报告

100729 G 解题报告

absi2011 posted @ 9 年前 in 刷题记录 with tags CF Gym 图论 , 520 阅读

题目链接:http://codeforces.com/gym/100729/attachments/download/3754/20112012-northwestern-european-regional-contest-nwerc-2011-en.pdf

这道题大概意思:

给你m个条件,n个人的坐标

"A听到,B比C先开枪"

然而,你需要考虑340m/s的声速的问题

所以,现在你要求出真正的开枪顺序,如果不能确定"UNKNOWN"信息有误"IMPOSSIBLE"

我们来考虑

A先听到B而不是C

那么就有B-->C的一条边

代表在C发枪val(b,c)秒后,B一定会发枪

那么我们floyd一次

如果出现val(i,i)<0,代表在i发枪前i秒,i一定会发枪,显然错,Impossible

如果出现val(i,j)>0且val(j,i)>0且i!=j,代表i和j之间发枪关系没定,显然Unknown了

其他情况,直接暴力找val全<0的即可.注意不要在任何时候去统计没发枪的人.

代码:

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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<math.h>
#include<string>
#include<time.h>
#include<bitset>
#include<vector>
#include<memory>
#include<utility>
#include<stdio.h>
#include<sstream>
#include<fstream>
#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std;
map<string,int> ma;
int x[105],y[105];
char a[1005];
double dist[105][105];
double val[105][105];
bool gun[105];
string name[1005];
int main()
{
    #ifdef absi2011
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    int t;
    scanf("%d",&t);
    int zu;
    for (zu=0;zu<t;zu++)
    {
        ma.clear();
        int n,m;
        scanf("%d%d",&n,&m);
        int i;
        for (i=0;i<n;i++)
        {
            scanf("%s%d%d",a,&x[i],&y[i]);
            string b=a;
            ma[b]=i;
            name[i]=b;
        }
        for (i=0;i<n;i++)
        {
            int j;
            for (j=0;j<n;j++)
            {
                dist[i][j]=sqrt((double)(x[i]-x[j])*(x[i]-x[j])+(double)(y[i]-y[j])*(y[i]-y[j]));
                val[i][j]=1e12;
            }
            gun[i]=false;
        }
        int j,k;
        for (i=0;i<m;i++)
        {
            scanf("%s",a);
            string b=a;
            int x=ma[b];
            scanf("%s",a);
            scanf("%s",a);
            b=a;
            int y=ma[b];
            scanf("%s",a);
            scanf("%s",a);
            scanf("%s",a);
            b=a;
            int z=ma[b];
            val[y][z]=min(val[y][z],dist[x][z]-dist[x][y]);
            gun[y]=true;
            gun[z]=true;
        }
        for (k=0;k<n;k++)
        {
            for (i=0;i<n;i++)
            {
                for (j=0;j<n;j++)
                {
                    if ((k==i)||(k==j)) continue;
                    val[i][j]=min(val[i][j],val[i][k]+val[k][j]);
                }
            }
        }
        for (i=0;i<n;i++)
        {
            if (val[i][i]<0)
            {
                puts("IMPOSSIBLE");
                break;
            }
        }
        if (i!=n) continue;
        for (i=0;i<n;i++)
        {
            if (!gun[i]) continue;
            int j;
            for (j=0;j<n;j++)
            {
                if (!gun[j]) continue;
                if (i==j) continue;
                if ((val[i][j]>0)&&(val[j][i]>0))
                {
                    puts("UNKNOWN");
                    break;
                }
            }
            if (j!=n) break;
        }
        if (i==n)
        {
            for (k=0;k<n;k++)
            {
                for (i=0;i<n;i++)
                {
                    if (!gun[i]) continue;
                    for (j=0;j<n;j++)
                    {
                        if (!gun[j]) continue;
                        if (i==j) continue;
                        if (val[i][j]>0) break;
                    }
                    if (j==n)
                    {
                        printf("%s ",name[i].c_str());
                        gun[i]=false;
                        break;
                    }
                }
            }
            puts("");
        }
    }
    return 0;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter