# uvalive 3713 Astronauts

2-SAT问题

  1 #include <stdio.h>
2 #include <string.h>
3 #include <iostream>
4 #include <vector>
5 #include <algorithm>
6 using namespace std;
7
8 const int maxn = 100005;
9 int a[maxn];
10
11 struct twosat
12 {
13     int n;
14     vector<int> g[maxn*2];
15     bool mark[maxn*2];
16     int s[maxn*2],c;
17
18     bool dfs(int x)
19     {
20         if (mark[x^1]) return false;
21         if (mark[x]) return true;
22
23         mark[x] = true;
24
25         s[c++] = x;
26
27         for (int i = 0;i < g[x].size();i++)
28         {
29             if (!dfs(g[x][i])) return false;
30         }
31
32         return true;
33     }
34
35     void init(int n)
36     {
37         this -> n = n;
38
39         for (int i = 0;i <= n * 2;i++) g[i].clear();
40
41         memset(mark,0,sizeof(mark));
42     }
43
44     void add_clause(int x,int xval,int y,int yval)
45     {
46         x = 2 * x + xval;
47         y = 2 * y + yval;
48
49         g[x^1].push_back(y);
50         g[y^1].push_back(x);
51     }
52
53     bool solve()
54     {
55         for (int i = 0;i < 2 * n;i += 2)
56         {
57             if (!mark[i] && !mark[i+1])
58             {
59                 c = 0;
60
61                 if (!dfs(i))
62                 {
63                     while (c > 0) mark[s[--c]] = 0;
64
65                     if (!dfs(i+1)) return false;
66                 }
67             }
68         }
69
70         return true;
71     }
72 } twosat;
73
74 int main()
75 {
76     int n,m;
77     //int kase = 0;
78
79     while (scanf("%d%d",&n,&m) != EOF)
80     {
81         if (n == 0 && m == 0) break;
82
83         int ave = 0;
84
85         for (int i = 0;i < n;i++)
86         {
87             scanf("%d",&a[i]);
88             ave += a[i];
89         }
90
91         //ave /= n;
92
93         twosat.init(n);
94
95         for (int i = 0;i < m;i++)
96         {
97             int x,y;
98
99             scanf("%d%d",&x,&y);
100
101             x--,y--;
102
103             //if (x == y) continue;
104
105             if (a[x] * n < ave && a[y] * n < ave)
106             {
109             }
110             else if (a[x] * n >= ave && a[y] * n >= ave)
111             {
114             }
115             else
116             {
118             }
119         }
120
121         if (twosat.solve())
122         {
123             for (int i = 0;i < n;i++)
124             {
125                 if (a[i] * n >= ave)
126                 {
127                     if (twosat.mark[2*i+1]) printf("A\n");
128                     else printf("C\n");
129                 }
130                 else
131                 {
132                     if (twosat.mark[2*i+1]) printf("B\n");
133                     else printf("C\n");
134                 }
135             }
136         }
137         else
138         {
139             printf("No solution.\n");
140         }
141
142         //printf("\n");
143     }
144
145     return 0;
146 }

• 0
点赞
• 0
收藏
觉得还不错? 一键收藏
• 0
评论
03-10
05-29 1109

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

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

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