[cf1038E][欧拉路]
You are given nn blocks, each of them is of the form [color11 |value|color22 ], where the block can also be flipped to get [color22 |value|color11 ].
A sequence of blocks is called valid if the touching endpoints of neighboring blocks have the same color. For example, the sequence of three blocks A, B and C is valid if the left color of the B is the same as the right color of the A and the right color of the B is the same as the left color of C.
The value of the sequence is defined as the sum of the values of the blocks in this sequence.
Find the maximum possible value of the valid sequence that can be constructed from the subset of the given blocks. The blocks from the subset can be reordered and flipped if necessary. Each block can be used at most once in the sequence.
The first line of input contains a single integer nn (1≤n≤1001≤n≤100 ) — the number of given blocks.
Each of the following nn lines describes corresponding block and consists of color1 value and color2 (1≤color1,color2≤4 1≤value≤100000).
Print exactly one integer — the maximum total value of the subset of blocks, which makes a valid sequence.
6
2 1 4
1 2 4
3 4 4
2 8 3
3 16 3
1 32 2
63
7
1 100000 1
1 100000 2
1 100000 2
4 50000 3
3 50000 4
4 50000 4
3 50000 3
300000
4
1 1000 1
2 500 2
3 250 3
4 125 4
1000
In the first example, it is possible to form a valid sequence from all blocks.
One of the valid sequences is the following:
[4|2|1] [1|32|2] [2|8|3] [3|16|3] [3|4|4] [4|1|2]
The first block from the input ([2|1|4] →→ [4|1|2]) and second ([1|2|4] →→ [4|2|1]) are flipped.
In the second example, the optimal answers can be formed from the first three blocks as in the following (the second or the third block from the input is flipped):
[2|100000|1] [1|100000|1] [1|100000|2]
In the third example, it is not possible to form a valid sequence of two or more blocks, so the answer is a sequence consisting only of the first block since it is the block with the largest value.
题意:有n个木棒,每个木棒两段有两种颜色,总颜色数<=4,两个木棒颜色一样的一段可以连接起来,得到的新木棒的价值为vi+vj,求拼接后得到的新木棒的最大价值
题解:可以把颜色看成点,木棒看成边,那么由于每种木棒只能使用一次,所以最终结果就是求一条权值和最大的欧拉路(每条边只经过一次的路径)。1)如果图中的度为奇数的点的个数<=2,那么该图是个欧拉图,权值和也就是该图的权值和,2)而本题的点数只有4个,所以如果不是欧拉图,那么度为奇数的点一定是4个,则此时要删掉一条连接两个度为奇数的边,则可以枚举这条要被删掉的边从而得到最大值(注意这个图不一定是连通图,所以要用dfs标记得到所有连通块)
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<vector> 6 #include<queue> 7 using namespace std; 8 //#define io_test 9 #define debug(x,y) cout<<x/2+1<<"#######"<<y/2+1<<"####"<<dp[x]<<endl; 10 vector<int>g[5]; 11 struct edge{ 12 int x; 13 int y; 14 int q; 15 int val; 16 int nex; 17 }e[20005]; 18 int vis[5]; 19 int cnt,head[5],bk[5],d[5]; 20 void adde(int x1,int y1,int z1){ 21 e[cnt].x=x1; 22 e[cnt].y=y1; 23 e[cnt].val=z1; 24 e[cnt].q=0; 25 e[cnt].nex=head[x1]; 26 head[x1]=cnt++; 27 e[cnt].x=y1; 28 e[cnt].y=x1; 29 e[cnt].val=z1; 30 e[cnt].q=0; 31 e[cnt].nex=head[y1]; 32 head[y1]=cnt++; 33 } 34 void dfs(int u,int col){ 35 vis[u]=col; 36 for(int i=head[u];i!=-1;i=e[i].nex){ 37 int v=e[i].y; 38 if(e[i].q)continue; 39 if(!vis[v]){ 40 dfs(v,col); 41 } 42 } 43 } 44 int oula(){ 45 int cnt=0; 46 int ans=0; 47 memset(vis,0,sizeof(vis)); 48 for(int i=1;i<=4;i++){ 49 if(!vis[i]){ 50 cnt++; 51 dfs(i,cnt); 52 int sum=0; 53 int odd=0; 54 for(int j=1;j<=4;j++){ 55 if(vis[j]==cnt){ 56 sum+=bk[j]; 57 if(d[j]%2)odd++; 58 } 59 } 60 if(odd<=2)ans=max(ans,sum); 61 } 62 } 63 return ans; 64 } 65 int main() 66 { 67 #ifdef io_test 68 freopen("in.txt","r",stdin); 69 freopen("out.txt","w",stdout); 70 #endif // io_test 71 int n; 72 int sum=0; 73 scanf("%d",&n); 74 memset(head,-1,sizeof(head)); 75 for(int i=1;i<=n;i++){ 76 int c1,v1,c2; 77 scanf("%d%d%d",&c1,&v1,&c2); 78 adde(c1,c2,v1); 79 d[c1]++; 80 d[c2]++; 81 bk[c2]+=v1; 82 } 83 int ss=oula(); 84 if(ss){ 85 printf("%d\n",ss); 86 } 87 else{ 88 int ans=0; 89 for(int i=1;i<=4;i++){ 90 if(d[i]&1){ 91 for(int j=head[i];j!=-1;j=e[j].nex){ 92 int v=e[j].y; 93 d[i]--; 94 d[v]--; 95 e[j].q=1; 96 e[j^1].q=1; 97 ans=max(ans,oula()-e[j].val); 98 d[i]++; 99 d[v]++; 100 e[j].q=0; 101 } 102 103 } 104 } 105 printf("%d\n",ans); 106 } 107 return 0; 108 }