[***] HZOJ day she can come back to me

%%% immortal title.

Actually graph theory, I always thought it was or what bipartite graph data structure.

Direct that a positive solution will be seen as the number of nodes, seen as the brand side, to the front of the card number from the back side to the right side even 1, anti-facing front right side even to the side of 0 (note use of paired storage skills, to be followed very cleverly used), can be found is to ask a few reverse side can make each point a reading of less than or equal to 1. Then each tree can only be connected graph or tree ring. Analyzing can be determined for each link to dfs FIG np points and edges ne, if ne / 2 (two-way side)> np, then the output is directly connected graph illegal to -1-1.

 1 void dfs(int x,int fa)
 2 {
 3     vi[x]=1;np++;
 4     for(int i=f(x);i;i=n(i))
 5     {
 6             ne++;
 7         if(v(i)!=fa)
 8             if(!vi[v(i)])dfs(v(i),x);
 9     }
10 }
11 bool pd()
12 {
13     for(int i=1;i<=n*2; i ++ )
 14      if (! vi [i])
 15      {
 16          np = ne = 0 , dfs (i, 0 );
17          if (np <ne / 2 ) return  1 ;
18      }
 19      return  0 ;
20 }
Code

Next, consider the case of the tree he was:

For with the node identified, the number of flip side is that all points to the parent node (can begin painting it), you can use the tree dp obtained. But to enumerate the root it? In fact, can use the secondary scanning method and the root change, x is a number set to the root side is to be inverted F [x], then the fact f [son] may be F [x] Update: If x-> son edges right to 1, then f [son] = f [x] -1, or f [son] = f [x] +1. so we solved the case of the tree.

 1 int f[MAXN],st,en,ned;
 2 void dfs1(int x,int fa)
 3 {
 4     v[x]=1;f[x]=0;
 5     for(int i=f(x);i;i=n(i))
 6     if(v(i)!=fa)
 7     {
 8         if(!v[v(i)])
 9         {
10             dfs1(v(i),x);
11             f[x]+=f[v(i)]+w(i);
12         }
13         else st=u(i),en=v(i),ned=i;
14     }
15 }
16 int f2[MAXN];
17 vector<int> tem;
18 void dfs2(int x,int fa)
19 {
20     tem.push_back(f2[x]);
21     for(int i=f(x);i;i=n(i))
22     if(v(i)!=fa && i!=ned && i!=(ned^1))
23     {
24         if(w(i))f2[v(i)]=f2[x]-1;
25         else    f2[v(i)]=f2[x]+1;
26         dfs2(v(i),x);
27     }
28 }
Code

See the following ring group tree:

Identify random on the ring at an edge dfs record, it is removed by the tree, and finally in consideration of the influence of this edge. Then there is the side paired with the storage, the number of edges is that it points to 2% weight v from u.

1                  down% = 2 ;
2                  if (f2 [st] + down == f2 [one] + (down ^ 1 )) minn = 2 ;
3                  else minn = 1 ;
4                  ans + = min (f2 [st] + down, f2 [one] + (down ^ 1 ));
Code
  1 #include<algorithm>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<cstdio>
  5 #include<vector>
  6 #define MAXN 200010
  7 #define mod 998244353
  8 #define LL long long
  9 #define int LL
 10 #define ma(x) memset(x,0,sizeof(x))
 11 using namespace std;
 12 struct edge
 13 {
 14     int u,v,w,nxt;
 15     #define u(x) ed[x].u
 16     #define v(x) ed[x].v
 17     #define w(x) ed[x].w
 18     #define n(x) ed[x].nxt
 19 }ed[MAXN*2];
 20 int first[MAXN],num_e=1;
 21 #define f(x) first[x]
 22 int T,n;
 23 
 24 int np,ne;
 25 bool v[MAXN],vi[MAXN];
 26 void dfs(int x,int fa)
 27 {
 28     vi[x]=1;np++;
 29     for(int i=f(x);i;i=n(i))
 30     {
 31             ne++;
 32         if(v(i)!=fa)
 33             if(!vi[v(i)])dfs(v(i),x);
 34     }
 35 }
 36 bool pd()
 37 {
 38     for(int i=1;i<=n*2;i++)
 39     if(!vi[i])
 40     {
 41         np=ne=0,dfs(i,0);
 42         if(np<ne/2)return 1;
 43     }
 44     return 0;
 45 }
 46 int f[MAXN],st,en,ned;
 47 void dfs1(int x,int fa)
 48 {
 49     v[x]=1;f[x]=0;
 50     for(int i=f(x);i;i=n(i))
 51     if(v(i)!=fa)
 52     {
 53         if(!v[v(i)])
 54         {
 55             dfs1(v(i),x);
 56             f[x]+=f[v(i)]+w(i);
 57         }
 58         else st=u(i),en=v(i),ned=i;
 59     }
 60 }
 61 int f2[MAXN];
 62 vector<int> tem;
 63 void dfs2(int x,int fa)
 64 {
 65 //    v[x]=1;
 66     tem.push_back(f2[x]);
 67     for(int i=f(x);i;i=n(i))
 68     if(v(i)!=fa && i!=ned && i!=(ned^1))
 69     {
 70         if(w(i))f2[v(i)]=f2[x]-1;
 71         else    f2[v(i)]=f2[x]+1;
 72 //        if(!v[v(i)])
 73         dfs2(v(i),x);
 74     }
 75 }
 76 inline void add(int u,int v,int w);
 77 signed main()
 78 {
 79 //    freopen("back5.in","r",stdin);
 80 //    freopen("1.out","w",stdout);
 81     
 82     cin>>T;
 83     while(T--)
 84     {
 85         ma(f);ma(f2);ma(v);ma(vi);ma(first);num_e=1;tem.clear();
 86         scanf("%lld",&n);
 87         int a,b;
 88         for(int i=1;i<=n;i++)
 89         {
 90             scanf("%lld%lld",&a,&b);
 91             add(a,b,1);add(b,a,0);
 92         }
 93         if(pd()){puts("-1 -1");continue;}
 94         int minn=0,ans=0,ans2=1;
 95         for(int i=1;i<=n*2;i++)
 96         if(!v[i])
 97         {    
 98             st=en=ned=-1;tem.clear();minn=0;
 99             dfs1(i,0);
100             f2[i]=f[i];
101             dfs2(i,0);
102             if(st==-1)
103             {
104                 sort(tem.begin(),tem.end());
105                 for(int j=0;j<tem.size();j++)
106                 if(tem[j]==tem[0])minn++;
107                 else break;
108                 ans+=tem[0];
109             }
110             else 
111              {
 112                  down% = 2 ;
113                  if (f2 [st] + down == f2 [one] + (down ^ 1 )) minn = 2 ;
114                  else minn = 1 ;
115                  ans + = min (f2 [st] + down, f2 [one] + (down ^ 1 ));
116              }
 117              ans2 = (ans2 * memory)% mod;
118          }
 119          printf ( " % lld% lld \ n " , ans, ans2);
120      }
 121  }
 122 inlinevoid add ( int u, int v, int w)
 123  {
 124      ++ num_e;
125      u (num_e) = u;
126      v (num_e) = v;
127      w (num_e) = w;
128      n (num_e) = f (u);
129      f (u) = num_e;
130 }
The complete code

 

Guess you like

Origin www.cnblogs.com/Al-Ca/p/11219279.html