题目链接

题意:

给出一个无向图,类似三角形的样子,然后给出边的权值,问找一条从第一个点到最后一个点的路径,要求每一条边只能走一次,并且权值和最大,点可以重复走。

思路:

首先观察这个图可以发现,所有的点的度数都是偶数。然后由每条边只能走一次知道,这个是和欧拉路相关的,是欧拉道路,不是欧拉回路,因为题目要求是从一个点到另一个点。但是图的所有点的度数都是偶数,那么想办法让图中的第一个点和最后一个点度数变为奇数,其他点的度数都是偶数。这个就比较巧妙,去掉从第一个点到最后一个点的一条无重复点的路径,除了起点和终点度数减1,其它点的度数都减2,目的就达到了。由于题目要求最后走的边的权值和最大,所以去掉的边的权值尽量小,那么从起点到终点求一个最短路即可。

求路径的方法是首先标记最短路上的边,然后从起点或终点开始dfs,走过的每条边标记(注意这是无向图,所以反向路径也要标记),当一个点再无边可走的时候,就把它放入路径中,这样可以保证求出的一定是一个欧拉道路。

代码:

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <algorithm>
  4. #include <vector>
  5. #include <queue>
  6. using namespace std;
  7. typedef long long ll;
  8. typedef pair<int,int> pii;
  9. const int N = 305;
  10. const int inf = 0x3f3f3f3f;
  11. struct edge
  12. {
  13. int u,v,cost;
  14. edge(int u,int v,int cost):u(u),v(v),cost(cost){}
  15. edge(){}
  16. };
  17. int a[N][N],b[N][N],c[N][N];
  18. int mp[N][N];
  19. vector<edge> es;
  20. vector<int> G[N*N];
  21. vector<pii> anc;
  22. void adde(int u,int v,int cost)
  23. {
  24. es.push_back(edge(u,v,cost));
  25. es.push_back(edge(v,u,cost));
  26. int sz = es.size();
  27. G[u].push_back(sz-2);
  28. G[v].push_back(sz-1);
  29. }
  30. ll dis[N*N];
  31. int rev[N*N];
  32. bool vis[N*N];
  33. bool used[N*N*8];
  34. pii rid[N*N];
  35. int cnt;
  36. void spfa()
  37. {
  38. for (int i = 0;i <= cnt;i++) dis[i] = 1e18;
  39. memset(vis,0,sizeof(vis));
  40. memset(rev,0,sizeof(rev));
  41. vis[1] = 1;
  42. dis[1] = 0;
  43. queue<int> q;
  44. q.push(1);
  45. while (!q.empty())
  46. {
  47. int u = q.front();
  48. q.pop();
  49. vis[u] = 0;
  50. for (int i = 0;i < G[u].size();i++)
  51. {
  52. edge &e = es[G[u][i]];
  53. int v = e.v;
  54. if (dis[v] > dis[u] + e.cost)
  55. {
  56. dis[v] = dis[u] + e.cost;
  57. rev[v] = G[u][i];
  58. if (!vis[v])
  59. {
  60. vis[v] = 1;
  61. q.push(v);
  62. }
  63. }
  64. }
  65. }
  66. }
  67. void dfs(int u)
  68. {
  69. for (int i = 0;i < G[u].size();i++)
  70. {
  71. int id = G[u][i];
  72. edge &e = es[id];
  73. if (!used[id])
  74. {
  75. used[id] = used[id^1] = 1;
  76. int v = e.v;
  77. dfs(v);
  78. }
  79. }
  80. anc.push_back(rid[u]);
  81. }
  82. void init()
  83. {
  84. cnt = 0;
  85. anc.clear();
  86. es.clear();
  87. for (int i = 0;i < N * N;i++) G[i].clear();
  88. }
  89. int main()
  90. {
  91. int t;
  92. scanf("%d",&t);
  93. while (t--)
  94. {
  95. int n;
  96. scanf("%d",&n);
  97. init();
  98. ll ans = 0;
  99. for (int i = 1;i < n;i++)
  100. {
  101. for (int j = 1;j <= i;j++)
  102. {
  103. scanf("%d",&a[i][j]);
  104. ans += a[i][j];
  105. }
  106. }
  107. for (int i = 1;i < n;i++)
  108. {
  109. for (int j = 1;j <= i;j++)
  110. {
  111. scanf("%d",&b[i][j]);
  112. ans += b[i][j];
  113. }
  114. }
  115. for (int i = 1;i < n;i++)
  116. {
  117. for (int j = 1;j <= i;j++)
  118. {
  119. scanf("%d",&c[i][j]);
  120. ans += c[i][j];
  121. }
  122. }
  123. for (int i = 1;i <= n;i++)
  124. {
  125. for (int j = 1;j <= i;j++)
  126. {
  127. mp[i][j] = ++cnt;
  128. rid[cnt] = pii(i,j);
  129. }
  130. }
  131. for (int i = 1;i < n;i++)
  132. {
  133. for (int j = 1;j <= i;j++)
  134. {
  135. int x = mp[i][j];
  136. int y = mp[i+1][j];
  137. adde(x,y,a[i][j]);
  138. y = mp[i+1][j+1];
  139. adde(x,y,b[i][j]);
  140. x = mp[i+1][j];
  141. y = mp[i+1][j+1];
  142. adde(x,y,c[i][j]);
  143. }
  144. }
  145. spfa();
  146. ans -= dis[cnt];
  147. memset(used,0,sizeof(used));
  148. for (int i = cnt;i != 1;i = es[rev[i]].u)
  149. {
  150. used[rev[i]] = used[rev[i]^1] = 1;
  151. }
  152. dfs(cnt);
  153. printf("%lld\n",ans);
  154. printf("%d\n",(int)anc.size());
  155. for (int i = 0;i < anc.size();i++)
  156. {
  157. printf("%d %d%c",anc[i].first,anc[i].second,i == anc.size() - 1 ? '\n' : ' ');
  158. }
  159. }
  160. return 0;
  161. }

zoj 4122 Triangle City 2019山东省赛J题的更多相关文章

  1. 山东省赛J题:Contest Print Server

    Description In ACM/ICPC on-site contests ,3 students share 1 computer,so you can print your source c ...

  2. 2013年山东省赛F题 Mountain Subsequences

    2013年山东省赛F题 Mountain Subsequences先说n^2做法,从第1个,(假设当前是第i个)到第i-1个位置上哪些比第i位的小,那也就意味着a[i]可以接在它后面,f1[i]表示从 ...

  3. hdu6578 2019湖南省赛D题Modulo Nine 经典dp

    目录 题目 解析 AC_Code @ 题目 第一题题意是一共有{0,1,2,3}四种数字供选择,问有多少个长度为n的序列满足所有m个条件,每个条件是说区间[L,R]内必须有恰好x个不同的数字. 第二题 ...

  4. HEX SDUT 3896 17年山东省赛D题

    HEX SDUT 3896 17年山东省赛D题这个题是从矩形的左下角走到右上角的方案数的变形题,看来我对以前做过的题理解还不是太深,或者是忘了.对于这种题目,直接分析它的性质就完事了.从(1,1)走到 ...

  5. luogu 1327 数列排序 & 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 J题 循环节

    luogu 1327 数列排序 题意 给定一个数列\(\{an\}\),这个数列满足\(ai≠aj(i≠j)\),现在要求你把这个数列从小到大排序,每次允许你交换其中任意一对数,请问最少需要几次交换? ...

  6. HDU 4800/zoj 3735 Josephina and RPG 2013 长沙现场赛J题

    第一年参加现场赛,比赛的时候就A了这一道,基本全场都A的签到题竟然A不出来,结果题目重现的时候1A,好受打击 ORZ..... 题目链接:http://acm.hdu.edu.cn/showprobl ...

  7. 模拟 2013年山东省赛 J Contest Print Server

    题目传送门 /* 题意:每支队伍需求打印机打印n张纸,当打印纸数累计到s时,打印机崩溃,打印出当前打印的纸数,s更新为(s*x+y)%mod 累计数清空为0,重新累计 模拟简单题:关键看懂题意 注意: ...

  8. The 10th Shandong Provincial Collegiate Programming Contest 2019山东省赛游记+解题报告

    比赛结束了几天...这篇博客其实比完就想写了...但是想等补完可做题顺便po上题解... 5.10晚的动车到了济南,没带外套有点凉.酒店还不错. 5.11早上去报道,济南大学好大啊...感觉走了一个世 ...

  9. [2019上海网络赛J题]Stone game

    题目链接 CSLnb! 题意是求出给定集合中有多少个合法子集,合法子集的定义为,子集和>=总和-子集和$\& \&$子集和-(子集的子集和)<=总和-子集和. 其实就是很简 ...

随机推荐

  1. 小米6使用charles抓包https

    1. 下载charles 地址: https://zhubangbang.com/charles-crack-version-free-download-and-install-tutorial.ht ...

  2. docker 启动镜像报 WARNING: IPv4 forwarding is disabled. Networking will not work.

    centos7 解决办法: # vi /etc/sysctl.conf 添加如下代码:     net.ipv4.ip_forward=1 重启network服务 # systemctl restar ...

  3. 【VS开发】这就是COM组件

    [实例]这就是COM组件 时间 2012-02-21 10:49:15  CSDN博客 原文  http://blog.csdn.net/btwsmile/article/details/727849 ...

  4. Node原生demo

    1.=>创建配置模块,作用是先判断是开发环境还是生产环境,并将开发或生产环境的数据库信息和http信息分别筛开,便于选择 2.=>创建数据库模块,作用是连接数据库 3.=>创建路由模 ...

  5. hdoj6446(树形DP)

    题目链接:https://vjudge.net/problem/HDU-6446 题意:简化题意后就是求距离和的2*(n-1)!倍. 思路: 简单的树形dp,通过求每条边的贡献计算距离和,边(u,v) ...

  6. chrome xpath调试

  7. 【LOJ】#2983. 「WC2019」数树

    LOJ2983. 「WC2019」数树 task0 有\(i\)条边一样答案就是\(y^{n - i}\) task1 这里有个避免容斥的方法,如果有\(i\)条边重复我们要算的是\(y^{n - i ...

  8. 1-N(1的总数)找规律

    见:https://blog.csdn.net/dormousenone/article/details/75208903 #define IOS ios_base::sync_with_stdio( ...

  9. gin框架博客实战教程2019web页面开发go语言实战博客开发

    视频教程: https://www.bilibili.com/video/av73698322?t=2400&p=5 资料下载地址(含数据库和main.go和controller里的代码) 注 ...

  10. Codeforces 1238F. The Maximum Subtree

    传送门 考虑构造一些区间使得树尽可能的 "大" 发现这棵树最多就是一条链加上链上出去的其他边连接的点 构造的区间大概长这样(图比较丑请谅解..$qwq$,图中每一个 "└ ...