POJ 2723

逻辑错误的代码
  1 //想了很久,发现自己做这道题时犯了一个大BUG。我的思路是,把一组钥匙看成一对X,-X。把
  2 //门确定的关系连边。其实这样是有错的,因为边的意义是“必须”,而实际上,门确定的只是矛盾
  3 //关系。不是必须是,不是门上锁其中一个选或不选就能影响到另一个。 
  4 
  5 #include <iostream>
  6 #include <cstdio>
  7 #include <cstring>
  8 #include <algorithm>
  9 using namespace std;
 10 
 11 const int MAXN=3200;
 12 const int MAXM=8000;
 13 
 14 int bel[MAXN],head[MAXN],dfn[MAXN],low[MAXN],st[MAXN],stop,index,tot;
 15 int belong[MAXN],pat;
 16 bool stack[MAXN];
 17 
 18 struct {
 19     int u,v;
 20     int next,Id;
 21 }edge[MAXM];
 22 int n,m;
 23 
 24 void addedge(int u,int v){
 25     edge[tot].u=u;
 26     edge[tot].v=v;
 27     edge[tot].Id=tot;
 28     edge[tot].next=head[u];
 29     head[u]=tot++;
 30 }
 31 
 32 void init(){
 33     for(int i=0;i<n*2;i++){
 34         dfn[i]=low[i]=0;
 35         stack[i]=false;
 36         belong[i]=-1;
 37     }
 38     stop=0; index=0; pat=-1;
 39 }
 40 
 41 void tarjan(int u,int limited){
 42     int v;
 43     dfn[u]=low[u]=++index;
 44     st[stop++]=u;
 45     stack[u]=true;
 46     for(int e=head[u];e!=-1;e=edge[e].next){
 47         if(edge[e].Id<=limited){
 48             v=edge[e].v;
 49             if(dfn[v]==0){
 50                 tarjan(v,limited);
 51                 low[u]=min(low[u],low[v]);
 52             }
 53             else if(stack[v]){
 54                 low[u] = min(low[u], dfn[v]);
 55             }
 56         }
 57     }
 58     if(dfn[u]==low[u]){
 59         pat++;
 60         do{
 61             v=st[--stop];
 62             stack[v]=false;
 63             belong[v]=pat;
 64         }while(u!=v);
 65     }
 66 }
 67 
 68 bool slove(int mid){
 69     init();
 70     for(int i=0;i<2*n;i++){
 71         if(dfn[i]==0){
 72             tarjan(i,mid);
 73         }
 74     }
 75     bool flag=true;
 76     for(int i=0;i<n;i++){
 77         if(belong[i]==belong[2*i+1]){
 78             flag=false;
 79             break;
 80         }
 81     }
 82     return flag;
 83 }
 84 
 85 int main(){
 86     int u,v,t; int s1,s2;
 87     while(scanf("%d%d",&n,&m)!=EOF){
 88         if(n==0&&m==0) break;
 89         for(int i=0;i<=2*n;i++)
 90         head[i]=-1;
 91         tot=1;
 92         for(int i=0;i<n;i++){
 93             scanf("%d%d",&u,&v);
 94             bel[u]=2*i; bel[v]=2*i+1;
 95         }
 96         for(int i=1;i<=m;i++){
 97             scanf("%d%d",&u,&v);
 98             s1=bel[u]; s2=bel[v];
 99             addedge(s1^1,s2);
100             addedge(s2^1,s1);
101         }
102         int lown,high,mid;
103         lown=1;high=m; int ans;
104         while(lown<=high){
105             mid=(lown+high)/2;
106             if(slove(mid*2)){
107             //    cout<<mid<<endl;
108                 ans=mid; lown=mid+1;
109             }
110             else high=mid-1;
111         }
112         printf("%d\n",ans);
113     }
114     return 0;
115 }
View Code

 

 

别人的代码。已明白错在哪里。。。只是不想写了。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <vector>
  6 #include <queue>
  7 #define MAXN 5005
  8 #define MAXM 50005
  9 #define INF 1000000000
 10 using namespace std;
 11 struct Edge
 12 {
 13     int v, next;
 14 }edge[MAXM];
 15 int n, m, e;
 16 int top, scc, index;
 17 int low[MAXN], dfn[MAXN], instack[MAXN];
 18 int head[MAXN], st[MAXN], fa[MAXN];
 19 int a[MAXN], b[MAXN], hash[MAXN];
 20 int x[MAXN], y[MAXN];
 21 void init()
 22 {
 23     top = scc = index = e = 0;
 24     memset(head, -1, sizeof(head));
 25     memset(dfn, 0, sizeof(dfn));
 26     memset(instack, 0, sizeof(instack));
 27 }
 28 void insert(int x, int y)
 29 {
 30     edge[e].v = y;
 31     edge[e].next = head[x];
 32     head[x] = e++;
 33 }
 34 void tarjan(int u)
 35 {
 36     low[u] = dfn[u] = ++index;
 37     instack[u] = 1;
 38     st[++top] = u;
 39     int v;
 40     for(int i = head[u]; i != -1; i = edge[i].next)
 41     {
 42         v = edge[i].v;
 43         if(!dfn[v])
 44         {
 45             tarjan(v);
 46             low[u] = min(low[u], low[v]);
 47         }
 48         else if(instack[v]) low[u] = min(low[u], dfn[v]);
 49     }
 50     if(dfn[u] == low[u])
 51     {
 52         scc++;
 53         do
 54         {
 55             v = st[top--];
 56             instack[v] = 0;
 57             fa[v] = scc;
 58         }while(v != u);
 59     }
 60 }
 61 bool check(int n)
 62 {
 63     for(int i = 1; i <= n; i++)
 64         if(fa[i] == fa[i + n]) return false;
 65     return true;
 66 }
 67 void build(int bound)
 68 {
 69     init();
 70     for(int i = 1; i <= n; i++)
 71     {
 72         insert(a[i], b[i] + 2 * n);
 73         insert(b[i], a[i] + 2 * n);
 74     }
 75     for(int i = 1; i <= bound; i++)
 76     {
 77         insert(x[i] + 2 * n, y[i]);
 78         insert(y[i] + 2 * n, x[i]);
 79     }
 80     for(int i = 1; i <= 2 * n; i++)
 81         if(!dfn[i]) tarjan(i);
 82 }
 83 void solve()
 84 {
 85     int ans = 0;
 86     int low = 0, high = m;
 87     while(low <= high)
 88     {
 89         int mid = (low + high) >> 1;
 90         build(mid);
 91         if(check(n * 2)) ans = max(ans, mid), low = mid + 1;
 92         else high = mid - 1;
 93     }
 94     printf("%d\n", ans);
 95 }
 96 int main()
 97 {
 98     while(scanf("%d%d", &n, &m) != EOF)
 99     {
100         if(n == 0 && m == 0) break;
101         for(int i = 1; i <= n; i++)
102         {
103             scanf("%d%d", &a[i], &b[i]);
104             a[i]++; b[i]++;
105         }
106         for(int i = 1; i <= m; i++)
107         {
108             scanf("%d%d", &x[i], &y[i]);
109             x[i]++; y[i]++;
110         }
111         solve();
112     }
113     return 0;
114 }
View Code
posted @ 2014-07-19 20:50  chenjunjie1994  阅读(144)  评论(0编辑  收藏  举报