Poj3387[neerc2006]idealframe

Source: Internet
Author: User
Tags in degrees

Actually, it's just a matter of forcing someone else's case.

before I write this, I will not be prepared for knowledge:

Oraton Road: One point to go through the path of all edges without repeating (can be stopped at another point)

Euler circuit: A point to start the loop without repeating all sides (must return to the starting point)

Eulerian graph: There is a diagram of the Euler circuit. The necessary and sufficient condition for judging the Eulerian graph graph is that all points have an even number of degrees.

Semi-Eulerian graph: A diagram of the existence of Euler pathways. The necessary and sufficient condition for judging the Eulerian graph graph is that all points have an even number of degrees or only two points are odd in degrees.

If there are points with an odd number of degrees in a graph, then such points must have even numbers.

Consider the complex examples from a few simple examples.

    1. The given graph is a ring, the answer is 0
    2. Given the graph is a Eulerian graph, then we just need to put the edges in accordance with the Euler loop to expand, the answer is more than 2 of the number of points. Because the final ring in a bit of the degree is 2, so the degree of more than 2 points must be fused, and there is only a fuse degree greater than 2 of the point of the scheme makes the Euler circuit into a ring.

For example, the left "8" glyph of the figure: from the middle of the point of 4 points between the upper and lower, to get to the right, purple node for the fused node formed a new node.

3. The given graph is a connected graph but not a Eulerian graph. Then the figure must contain an even number of odd points. So we can "pair" The Singularity Point 22, each pair of points with a "side", so that the original image into a all-point degree is even the Eulerian graph, you can expand it into a ring. This place is more difficult to understand, because the original question does not add edge operation, then how to even "edge" it? The key is: although we think that "add edge" and then "expand", but the actual operation, you need to first fuse operation, and then connect operation, because a point greater than 1 points can not be connected operation. So even the "edge" corresponds to the operation of the problem, is the two singular points of the fuse, and then they each produced a degree of 1 nodes connected together. When calculating the answer, it is first to count the number of odd points and the number of even points in the original image, and the cost of odd points/2 will be converted into Eulerian graph. Then count the number of points in the graph after "edge" to be greater than 2. Simply subtract the total number of points minus the last 2. Note that the point "edge" of the original degree of 1 becomes a point with a degree of 2.

Next, consider multiple connected blocks.

4. The given graph is not a connected graph, but each connected block is a chain. End-to-end, answer = number of links

5. The given graph is not a connected graph, but each connected block is a ring. Each ring is broken into a chain and then end to end, the answer = chain number x2

6. The given graph is not a connected graph, each connected block is a Eulerian graph but not a ring. Do we need to start with a couple of fuses to expand the Euler circuit into a ring and then break the ring into a chain with a single fuse? No need. In fact, we can "conveniently" pull the ring into a chain as we unfold it into a ring. Or the 8 figure above, we can complete the "Euler loop as a loop" and "split the chain" through a one-step fuse. Therefore, if a Euler loop is not a ring, we can complete the "tear-off chain" in the process of expanding it into a ring without the need for an additional fuse. The same is true for more complex graphs. Only a diagram that is originally a ring needs a single fuse "tear-off chain".

7. Multiple connected blocks, each connected block has no special properties (i.e. the original problem).

We want to turn each connected block into a chain and then connect each link to the end. So first count the cost of connecting all the chains and add the number of connected blocks to the answer.

We then calculate the minimum cost for each connected block to be broken into a chain. In essence we need to turn each connected block into a semi-Eulerian graph (a graph with a Euler's path) and then unfold. The cost of expanding the half-Eulerian graph into a chain and the cost of expanding the Eulerian graph into a ring can be calculated similarly, equal to the number of degrees greater than 2. This is followed by the number of singularity points discussed.

If the number of singular points of a connected block is exactly 2, we can calculate the cost of expanding the chain directly.

If the number of odd points is greater than 2, we need to use the "some associated fuse and connection operation" equivalent to "plus edge" idea, the number of odd points to 2, and statistics "plus" the number of connections required (the number of fuses is not counted here). Add the "Edge", you can count the cost of expanding into the chain.

If the number of odd points is 0 (is a Eulerian graph), we can calculate the cost of this connected block according to 6.

However, when writing the code, the test did not fully understand the nature of the above ... so I wrote a big lump of the classification discussion and manual enumeration, but also record the number of points in each connected block in degrees 1,2,3,4, and finally did not get the "split chain" can sometimes be used without the extra cost of nature, Add a bunch of inexplicable details to the error, only 70 ... If you figure out these properties, the code should not be so disgusting. This code is the test code based on the change, do not recommend to see, just let the reading of the puzzle you feel the nature of the writing code will lead to what consequences->_->

#include <cstdio>Const intmaxn=1005, maxm=50005;intU[MAXM],V[MAXM];intufs[maxn+maxm*2];inttot=0;intdeg[maxn+maxm*2];intFindintx) {    returnx==ufs[x]?x:ufs[x]=find (Ufs[x]);}voidLinkintAintb) {Ufs[find (a)]=find (b);}intodd[maxn+maxm*2],even[maxn+maxm*2],one[maxn+maxm*2],two[maxn+maxm*2],three[maxn+maxm*2],four[maxn+maxm*2];intscc[maxn+maxm*2];intCNT;intmaxdeg[maxn+maxm*2];intMain () {//freopen ("frame.in", "R", stdin);    intN,M;SCANF ("%d%d",&n,&m); Tot=N;  for(intI=1; i<=m;++i) {scanf ("%d%d", u+i,v+i); if(u[i]==0) u[i]=++tot; if(v[i]==0) v[i]=++tot; Deg[u[i]]+ +;d eg[v[i]]++; }     for(intI=1; i<=tot;++i) ufs[i]=i;  for(intI=1; i<=m;++i) {        if(Find (u[i])! =find (V[i]) Link (u[i],v[i]); }     for(intI=1; i<=tot;++i) {        if(deg[i]!=0){            if(deg[i]&1) Odd[find (i)]++; ElseEven[find (i)]++; if(deg[i]==1) One[find (i)]++; Else if(deg[i]==2) Two[find (i)]++; Else if(deg[i]==3) Three[find (i)]++; Else if(deg[i]==4) Four[find (i)]++; }    }     for(intI=1; i<=tot;++i) {        if(ufs[i]==i&&deg[i]!=0) {scc[++cnt]=i; }    }/*for (int i=1;i<=tot;++i) {if (Find (i) ==scc[4]) printf ("%d\n", I); }*/   //printf ("%d\n", CNT);    if(cnt==1){        intx=scc[1]; TWO[X]+=One[x]; EVEN[X]+=Odd[x]; intans=odd[x]/2+ (even[x]-two[x]); printf ("%d\n", ans); }Else{        inttoteven=0, tottwo=0; intans=0, X;  for(intI=1; i<=cnt;++i) {x=scc[i];//printf ("%4d%4d%4d%4d%4d%4d", odd[x],even[x],one[x],two[x],three[x],four[x]);            if(odd[x]==0){                if(four[x]!=0) {Two[x]++;odd[x]=one[x]=2; FOUR[X]--; }                Else if(two[x]!=0) {Two[x]--;even[x]--; ONE[X]=odd[x]=2; }Else{odd[x]=one[x]=2; } ans++; Tottwo+=Two[x]; Toteven+=Even[x]; }Else{//It is possible to break even point ...                if(one[x]>=2){//no need to dismantle 1.Odd[x]-=2; ONE[X]-=2; TWO[X]+=One[x]; Ans+=odd[x]/2; }Else if(one[x]==1){//one more 1 .                    if(three[x]!=0) {Three[x]--;ans++; TWO[X]++; ODD[X]-=2; EVEN[X]++; Ans+=odd[x]/2; }Else{//This is the split point, can I split the point? Odd[x]-=2; EVEN[X]++; Ans++; Ans+=odd[x]/2; }                }Else if(one[x]==0){//split the two 1                    intg1=0x7f7f7f7f, g2=0x7f7f7f7f, g3=0x7f7f7f7f, g4=0x7f7f7f7f, g5=0x7f7f7f7f; if(three[x]>=2){//split two X 3G1=2+ (odd[x]-2)/2; }                    if(two[x]!=0) {G2=1+odd[x]/2; }                    if(four[x]!=0) {G3=odd[x]/2-1; }                    if(three[x]!=odd[x]&&three[x]!=0) {G4=1+ (odd[x]-2)/2; }                    if(three[x]==0) {G5=2+ (odd[x]-2)/2; }                    if(g1<=g2&&g1<=g3&&g1<=g4&&g1<=g5) {ans+=2; ODD[X]-=2; even[x]+=2; two[x]+=2; Ans+ = (odd[x]/2); }Else if(g2<=g1&&g2<=g3&&g2<=g4&&g2<=g5) {ans+=1; TWO[X]--;even[x]--; Ans+=odd[x]/2; }Else if(g3<=g1&&g3<=g2&&g3<=g4&&g3<=g5) {Two[x]++;//ans+=1;ans+=odd[x]/2; }Else if(g4<=g1&&g4<=g2&&g4<=g3&&g4<=g5) {Two[x]++;even[x]+=2;//ans+=2;Odd[x]-=2; Ans+=odd[x]/2; }Else{//printf ("!");Even[x]+=2;//ans+=2;Odd[x]-=2; Ans+=odd[x]/2; }} tottwo+=Two[x]; Toteven+=even[x]+Odd[x]; }//printf ("Ansnow%d\n", ans);} ans+ = (toteven-tottwo); ans+=CNT; //printf ("%d%d\n", toteven,tottwo);printf ("%d\n", ans); }//while (1);    return 0;} 

Poj3387[neerc2006]idealframe

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.