弦图的判定

wywcgs提供了一份英文的论文,看了一下了解了大概的O(n + m)的算法的实现,但是自己一直RE- -b。

只写对了一个O(n ^ 2 + m)的模板。附带RE的O(n + M)的代码。

回来补关于弦图的其他算法。先果断TC呀。

ContractedBlock.gif ExpandedBlockStart.gif ZOJ 1015
 
   
1 #include < iostream >
2 #include < cstring >
3 #include < cstdio >
4   using namespace std;
5   const int N = 1001 ;
6 int maps[N][N], chk[N], cnt[N];
7 int order[N], q[N];
8
9 void build( int n)
10 {
11 memset(chk, 0 , sizeof (chk));
12 memset(cnt, 0 , sizeof (cnt));
13 for ( int i = n - 1 ;i >= 0 ;i -- )
14 {
15 int maxn = - 1 , idx = - 1 ;
16 for ( int j = 0 ;j < n;j ++ )
17 {
18 if ( ! chk[j] && maxn < cnt[j])
19 {
20 idx = j;maxn = cnt[j];
21 }
22 }
23 chk[idx] = true ;order[i] = idx;
24 for ( int j = 0 ;j < n;j ++ )
25 {
26 if ( ! chk[j] && maps[idx][j]) cnt[j] ++ ;
27 }
28 }
29 }
30
31 bool check( int n)
32 {
33 for ( int i = 0 ;i < n;i ++ )
34 {
35 int idx = - 1 , cnt = 0 ;
36 for ( int j = i;j < n;j ++ )
37 {
38 if (maps[order[i]][order[j]])
39 {
40 if (idx == - 1 ) idx = order[j];
41 else q[cnt ++ ] = order[j];
42 }
43 }
44 for ( int j = 0 ;j < cnt;j ++ )
45 if ( ! maps[idx][q[j]]) return false ;
46 }
47 return true ;
48 }
49 int main()
50 {
51 int n, m, a, b;
52 while (scanf( " %d %d " , & n, & m) == 2 && (n + m))
53 {
54 memset(maps, 0 , sizeof (maps));
55 while (m -- )
56 {
57 scanf( " %d %d " , & a, & b);
58 maps[a - 1 ][b - 1 ] = maps[b - 1 ][a - 1 ] = 1 ;
59 }
60 build(n);
61 puts(check(n) ? " Perfect\n " : " Imperfect\n " );
62 }
63 return 0 ;
64 }
65 /* const int N = 2000;
66 const int M = 100000;
67 int ll[N], rr[N], nxt[N], lv[N];
68 int chk[N], last[N], order[N], label[N];
69 int setB[N], maps[N][N];
70 struct edge
71 {
72 int v;
73 edge *nxt;
74 }*pp, pool[M], *g[N];
75
76 void addedge(int u,int v)
77 {
78 maps[u][v] = true;
79 pp->v = v;
80 pp->nxt = g[u];
81 g[u] = pp++;
82 }
83
84 void initialize()
85 {
86 memset(maps, 0, sizeof(maps));
87 memset(g, 0, sizeof(g));
88 pp = pool;
89 }
90
91 int deleteBucket(int u)
92 {
93 if(ll[u] != -1) rr[ll[u]] = rr[u];
94 if(rr[u] != -1) ll[rr[u]] = ll[u];
95 return ll[u];
96 }
97
98 void insertBucket(int u, int cnt)//在 u的上面插入一个桶cnt
99 {
100 rr[cnt] = rr[u];
101 ll[cnt] = u;
102 if(rr[u] != -1) ll[rr[u]] = cnt;
103 rr[u] = cnt;
104 }
105
106 void deleteList(int v)
107 {
108 if(ll[v] == -1) nxt[lv[v]] = rr[v];
109 else rr[ll[v]] = rr[v];
110 if(rr[v] != -1) ll[rr[v]] = ll[v];
111 }
112
113 void insertFront(int b, int v)
114 {
115 deleteList(v);
116 if(nxt[b] != -1) ll[nxt[b]] = v;
117 ll[v] = -1;
118 rr[v] = nxt[b];
119 nxt[b] = v;
120 }
121
122 void build(int n)
123 {
124 memset(nxt, -1, sizeof(nxt));
125 nxt[n] = 0;
126 ll[n] = rr[n] = -1;
127 ll[0] = -1, rr[n - 1] = -1;
128 for(int i = 0;i < n - 1;i++) rr[i] = i + 1;
129 for(int i = 1;i < n;i++) ll[i] = i - 1;
130 fill(lv, lv + n, n);
131 memset(chk, 0, sizeof(chk));
132 memset(last, -1, sizeof(last));
133 int high = n, cnt = n;
134 for(int j = n - 1;j >= 0;j--)
135 {
136 while(high != -1 && nxt[high] == -1)
137 high = deleteBucket(high);
138 if(high == -1) break;
139 int v = nxt[high];
140 deleteList(v);
141 chk[v] = true;
142 order[j] = v;
143 if(nxt[high] == -1) high = deleteBucket(high);
144 for(edge *i = g[v];i != NULL;i = i->nxt)
145 {
146 if(!chk[i->v])
147 {
148 if(rr[lv[i->v]] == -1)
149 {
150 high = ++cnt;
151 insertBucket(lv[i->v], cnt);
152 insertFront(cnt, i->v);
153 last[cnt] = j;
154 lv[i->v] = cnt;
155 }
156 else if(last[rr[lv[i->v]]] == j)
157 {
158 int u = rr[lv[i->v]];
159 insertFront(u, i->v);
160 lv[i->v] = u;
161 }
162 else
163 {
164 ++cnt;
165 insertBucket(lv[i->v], cnt);
166 insertFront(cnt, i->v);
167 last[cnt] = j;
168 lv[i->v] = cnt;
169 }
170 }
171 }
172 }
173 }
174 bool check(int n)
175 {
176 for(int i = 0;i < n;i++)
177 label[order[i]] = i;
178 for(int i = 0;i < n;i++)
179 {
180 int minn = 2 * n, y = -1;
181 int x = order[i];
182 int cnt = 0;
183 for(edge *j = g[x];j != NULL;j = j->nxt)
184 {
185 if(label[j->v] > i) setB[cnt++] = j->v;
186 if(minn > label[j->v] && label[j->v] > i)
187 {
188 minn = label[j->v];
189 y = j->v;
190 }
191 }
192 for(int j = 0;j < cnt;j++)
193 {
194 if(!maps[y][setB[j]] && y != setB[j])
195 return false;
196 }
197 }
198 return true;
199 }
200 int main()
201 {
202 int n, m, a, b;
203 while(scanf("%d %d", &n, &m) == 2 && (n + m))
204 {
205 initialize();
206 for(int i = 0;i < m;i++)
207 {
208 scanf("%d %d", &a, &b);
209 addedge(a - 1, b - 1);
210 addedge(b - 1, a - 1);
211 }
212 build(n);
213 puts(check(n) ? "Perfect" : "Imperfect");
214 }
215 return 0;
216 } */

转载于:https://www.cnblogs.com/ronaflx/archive/2011/05/03/2035594.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值