#C241122B. 三角图


#C241122B. 三角图

标签(Label)

  • 欧拉回路

网址(Website)

题目详情 - 三角图 - Super

题解 - 三角图 - Super

题目(Problem)

输入数据 1

4
4
4 2
1 2 3
4
1 2
1 3 3
2
4 3
1 4 3

输出数据 1

38

输入数据 2

5
9
3 9
4 8 7
6 6 7 5
3
9 3
7 7 5
8 4 6 8
9
7 5
9 8 3
8 7 6 4

输出数据 2

171

【样例3】

见选手目录下的 $triangle/triangle3.in$ 与 $triangle/triangle3.ans$。

【样例4】

见选手目录下的 $triangle/triangle4.in$ 与 $triangle/triangle4.ans$。

【样例5】

见选手目录下的 $triangle/triangle5.in$ 与 $triangle/triangle5.ans$。

题解(Solution)

这个东西肯定满足欧拉回路,欧拉回路的性质是每个点的度都是偶数,因此我们完全可以直接一笔画走完整张图并且走回 $(1,1)$ ,这个时候我们需要从 $(1,1)$ 走到 $(n,n)$ ,说白了就是加上从 $(1,1)$ 到 $(n,n)$ 的路径,我们就能走出一条完整的欧拉回路,最后的答案肯定就是边权和减去 $(1,1)\to(n,n)$ 的路径,那我们肯定要让这条路径最短,直接求最短路即可。

还有一个点我在考试的时候忽略了,就是会不会求出的路径使得剩下的路径无法连通,实际上因为由于数据范围中三角形的限制,所以对于一个三角形最短路最多经过一条边,一定会存在剩下两条边组成剩余路径,证毕。

出题者题解

代码(Code)

100分
#include<bits/stdc++.h>
#include<vector>
#include<queue>
#define For(i,l,r) for(int i=l;i<=r;i++)
#define ROf(i,l,r) for(int i=l;i>=r;i--)
#define show(a,b) For(i,1,n) cerr<<a[i]<<' ';cerr<<'\n';
using namespace std;
#define P pair<int,int>
#define int long long
#define x first
#define y second
inline int rd(){
	char c;bool f=false;while(!isdigit(c=getchar()))f=c=='-';int x=c^48;
	while(isdigit(c=getchar())){x=(((x<<2)+x)<<1)+(c^48);}return f?-x:x;
}template<typename G>
void write(G x){
	if(x<0) putchar('-'),write(-x);
	else if(x<=9) putchar(x+'0');
	else write(x/10), putchar(x%10+'0');
}constexpr int inf = 0x3f3f3f3f3f3f3f3f;
constexpr int N = 2005;
bool ST;double Tim;

/*
对于一个正方形(斜着的) 
可以从 (i,j) 走完整个正方形走到 (i+k,j+k)  ?
这就是欧拉回路的拓展
想到了入度和出度
因为这张图一定构成一张欧拉回路,所以从(1,1)走出一定可以回来
所以如果要到(n,n)就必须钦定一条从(n,n)回来的路,减去这条路的贡献
就变成了求最短路 
*/

int cha[N][N],cnt;//转成一维的点 
vector<P> ft[N*N];
int n,all;

priority_queue<P> q;
int dis[N*N];
void dijkstra(int st){
	memset(dis,0x3f,sizeof dis);
	dis[st] = 0, q.emplace(0,st);
	while(q.size()){
		int x=q.top().y;q.pop();
		for(auto p:ft[x]){
			int y,v;tie(y,v)=p;
			if(dis[x]+v < dis[y]){
				dis[y] = dis[x]+v;
				q.emplace(-dis[y],y);
			}
		}
	}
}

void Solve(){
	n=rd();For(i,1,n) For(j,1,i) cha[i][j]=++cnt;
	For(i,1,n-1) For(j,1,i){
		int x=cha[i][j], y=cha[i+1][j], v=rd();
		ft[x].emplace_back(y,v);
		ft[y].emplace_back(x,v);
		all+=v;
	}
	For(i,1,n-1) For(j,1,i){
		int x=cha[i][j], y=cha[i+1][j+1], v=rd();
		ft[x].emplace_back(y,v);
		ft[y].emplace_back(x,v);
		all+=v;
	}
	For(i,1,n-1) For(j,1,i){
		int x=cha[i+1][j], y=cha[i+1][j+1], v=rd();
		ft[x].emplace_back(y,v);
		ft[y].emplace_back(x,v);
		all+=v;
	}
	dijkstra(1);
	write(all-dis[cnt]), putchar('\n');
}

bool ED;
signed main(){
	cerr<<abs(&ST-&ED)/1024./1024.<<"MB\n";
	freopen("triangle.in","r",stdin);
	freopen("triangle.out","w",stdout);
	int Tt=1;Tim = clock();
	while(Tt--) Solve();
	return cerr<<"TIME:"<<(clock()-Tim)/CLOCKS_PER_SEC,0;
}

文章作者: WolfDeer
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 WolfDeer !
  目录