[***] When will HZOJ come back to me?

Posted by BlueGemini on Sun, 21 Jul 2019 15:47:55 +0200

%%% Immortality.

It's a graph theory. I always thought it was a bipartite graph or some data structure.

Directly speaking, the number is regarded as a node and the card is regarded as a side. From the number of the front side of the card to the side of the negative side with the right of 1 and the opposite side with the right of 0, we can find that we need to reverse several sides to make each point read less than or equal to 1. This is the case. Then each link graph can only be a tree or a base ring tree. The number of points NP and the number of edges NE can be determined by dfs. If ne/2 (bidirectional edges) > np, the graph can not be output directly - 1 - 1 illegally.

 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 implementation

Next, consider that he is a tree.

For a given heel node, the number of flipped edges is to point all points to the father node (you can draw it by hand), which can be obtained by using the tree dp. But do you want to enumerate the root nodes? In fact, it can be used to scan twice and change roots. If the number of edges to be reversed with X is f[x], then f[son] can be updated with f[x]: if the edge weight of X - > son is 1, then f[son]=f[x]-1, otherwise f[son]=f[x]+1. So we can solve the tree situation.

 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 implementation

Look at the base ring tree below.

In dfs, we find a random edge record on the ring, remove it and process it as a tree. Finally, we consider the influence of this edge. Then the paired storage of edges is useful. The number% 2 of edges is the weight from u to v.

1                 ned%=2;
2                 if(f2[st]+ned==f2[en]+(ned^1))minn=2;
3                 else minn=1;
4                 ans+=min(f2[st]+ned,f2[en]+(ned^1));
code implementation
  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                 ned%=2;
113                 if(f2[st]+ned==f2[en]+(ned^1))minn=2;
114                 else minn=1;
115                 ans+=min(f2[st]+ned,f2[en]+(ned^1));
116             }
117             ans2=(ans2*minn)%mod;
118         }
119         printf("%lld %lld\n",ans,ans2);
120     }
121 }
122 inline void 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 }
Complete code

Topics: PHP less