求助,大佬捞一捞,玄关
  • 板块灌水区
  • 楼主封禁用户
  • 当前回复20
  • 已保存回复20
  • 发布时间2023/8/18 10:47
  • 上次更新2023/11/3 02:58:00
查看原帖
求助,大佬捞一捞,玄关
1048440
封禁用户楼主2023/8/18 10:47

单源最短路板子题但是边权高精,调了2天了,还是只能过一个点(我是拿P3371测的),有没有大佬知道蒟蒻的代码哪里有问题,玄关注两个

#include<iostream>
#include<queue>
using namespace std;
#define N 20
struct Num { int num[N], cnt, f; };
inline void read(int x[], int& cnt, int& f) {//读入高精度数
	cnt = 0; f = 1; char ch = getchar();
	while (ch < '0' || ch>'9') { if (ch == '-') f = -f; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { x[++cnt] = ch - 48; ch = getchar(); }
	int lin[N] = {}; for (int i = cnt; i >= 1; i--) lin[i] = x[cnt - i + 1];
	for (int i = 1; i <= cnt; i++) x[i] = lin[i];
}
inline void write(int x[], int cnt, int f) {//输出高精度数
	if (f == -1 && !(cnt == 1 && x[cnt] == 0)) putchar('-'), f = -f;
	for (int i = cnt; i >= 1; i--) putchar(x[i] + '0');
	putchar(' '); return;
}
inline void copy(int x1[], int cnt1, int f1, int x2[], int& cnt2, int& f2) {//把高精度数x1完全复制给高精度数ans
	for (int i = 1; i <= cnt1; i++) x2[i] = x1[i];
	cnt2 = cnt1; f2 = f1;
}
inline void copynum(int x[],int &cnt,int &f,int num){
	if(num<0) f=-1,num=-num;
	else f=1;
	cnt=0;
	while(num>0) x[++cnt]=num%10,num/=10;
	while(x[cnt]==0&&cnt>0) cnt--;
	if(cnt==0) cnt++,x[cnt]=0;
}
inline int getnum(int x[],int cnt,int f){
	int num=0;
	for(int i=cnt;i>=1;i--) 
		num=num*10+x[i];
	return num;
}
inline bool same(int x1[],int cnt1,int f1,int x2[],int cnt2,int f2){
	if(f1!=f2) return false;
	if(cnt1!=cnt2) return false;
	for(int i=1;i<=cnt1;i++)
		if(x1[i]!=x2[i]) return false;
	return true;
}
inline void resetmax(int x[],int &cnt,int &f){
	cnt=N-5;f=1;
	for(int i=1;i<=cnt;i++)
		x[i]=9;
}
inline void getmax(int x1[], int cnt1, int f1, int x2[], int cnt2, int f2, int ans[], int& cntans, int& fans) {//获取最大值,存储到数组ans中
	if (f1 > f2) { copy(x1, cnt1, f1, ans, cntans, fans); return; }
	else if (cnt1 > cnt2) { copy(x1, cnt1, f1, ans, cntans, fans); return; }
	else if (f1 < f2) { copy(x2, cnt2, f2, ans, cntans, fans); return; }
	else if (cnt1 < cnt2) { copy(x2, cnt2, f2, ans, cntans, fans); return; }
	bool ismax = true;
	for (int i = cnt1; i >= 1; i--) if (x1[i] < x2[i]) { ismax = false; break; }
	if(ismax) { copy(x1, cnt1, f1, ans, cntans, fans); return; }
	else { copy(x2, cnt2, f2, ans, cntans, fans); return; }
}
inline void getmin(int x1[], int cnt1, int f1, int x2[], int cnt2, int f2, int ans[], int& cntans, int& fans) {//获取最小值,存储到数组ans中
	if (f1 < f2) { copy(x1, cnt1, f1, ans, cntans, fans); return; }
	else if (cnt1 < cnt2) { copy(x1, cnt1, f1, ans, cntans, fans); return; }
	else if (f1 > f2) { copy(x2, cnt2, f2, ans, cntans, fans); return; }
	else if (cnt1 > cnt2) { copy(x2, cnt2, f2, ans, cntans, fans); return; }
	bool ismax = true;
	for (int i = cnt1; i >= 1; i--) if (x1[i] > x2[i]) { ismax = false; break; }
	if (ismax) { copy(x1, cnt1, f1, ans, cntans, fans); return; }
	else { copy(x2, cnt2, f2, ans, cntans, fans); return; }
}
inline bool ismax(int x1[], int cnt1, int f1, int x2[], int cnt2, int f2) {//判断数x1是不是更大
	if (f1 > f2) return true;
	else if (cnt1 > cnt2) return true;
	else if (f1 < f2) return false;
	else if (cnt1 < cnt2) return false;
	bool ismax = true;
	for (int i = cnt1; i >= 1; i--) if (x1[i] < x2[i]) return false;
	return true;
}
inline bool ismin(int x1[], int cnt1, int f1, int x2[], int cnt2, int f2) {//判断数x1是不是更小
	if (f1 > f2) return false;
	else if (cnt1 > cnt2) return false;
	else if (f1 < f2) return true;
	else if (cnt1 < cnt2) return true;
	bool ismax = true;
	for (int i = cnt1; i >= 1; i--) if (x1[i] > x2[i]) return false;
	return true;
}
inline void add(int x1[], int cnt1, int x2[], int cnt2, int ans[], int &cntans) {//高精度加法,不考虑符号
	int len = max(cnt1, cnt2); int x = 0;
	if(len==cnt1) for(int i=cnt2+1;i<=len;i++) x2[i]=0;
	else for(int i=cnt1+1;i<=len;i++) x1[i]=0;
	for (int i = 1; i <= len; i++) {
		ans[i] = (x1[i] + x2[i] + x) % 10;
		x = (x1[i] + x2[i] + x) / 10;
	}if (x > 0) ans[++len] = x;
	cntans = len;
}
inline void _minus(int x1[], int cnt1, int x2[], int cnt2, int ans[], int &cntans,int &f) {//高精度减法,不考虑符号
	if (ismin(x1, cnt1, 1, x2, cnt2, 1)) {
		copy(x2, cnt2, 1, ans, cntans, f); f = -f;
		for (int i = cnt1; i >= 1; i--) {
			if (ans[i] < x1[i]) {
				int cnt = i + 1; ans[i] = ans[i] + 10 - x1[i];
				while (ans[cnt] == 0 && cnt <= cntans) ans[cnt] = 9, cnt++;
				ans[cnt]--; while (ans[cntans] == 0) cntans--;
			}
			else ans[i] -= x1[i];
		}while (cntans > 0 && ans[cntans] == 0) cntans--; if (cntans == 0) cntans++;
	}
	else {
		copy(x1, cnt1, 1, ans, cntans, f);
		for (int i = cnt2; i >= 1; i--) {
			if (ans[i] < x2[i]) {
				int cnt = i + 1; ans[i] = ans[i] + 10 - x2[i];
				while (ans[cnt] == 0 && cnt <= cntans) ans[cnt] = 9, cnt++;
				ans[cnt]--; while (ans[cntans] == 0) cntans--;
			}
			else ans[i] -= x2[i];
		}while (ans[cntans] == 0) cntans--; if (cntans == 0) cntans++;
	}
}
inline void Init(Num &a) { a.cnt = 1; a.f=1;a.num[1]=0;}
inline void Read(Num &a) { read(a.num, a.cnt, a.f); }
inline void Write(Num a) { write(a.num, a.cnt, a.f); }
inline void ResetMax(Num &a){resetmax(a.num,a.cnt,a.f);}
inline bool Same(Num a,Num b){return same(a.num,a.cnt,a.f,b.num,b.cnt,b.f);}
inline void Copy(Num a, Num &b) { copy(a.num, a.cnt, a.f, b.num, b.cnt, b.f); }//复制,把a复制给b 
inline void CopyNum(Num &a,int x){copynum(a.num,a.cnt,a.f,x);return;}//把int类型的变量x的值赋值给高精度数a 
inline bool SameNum(Num a,int x){Num b;CopyNum(b,0);return Same(a,b);}
inline int GetNum(Num a){return getnum(a.num,a.cnt,a.f);}//把低于10位的高精度数的值转化成int类型 
inline void GetMax(Num a, Num b, Num &c) { getmax(a.num, a.cnt, a.f, b.num, b.cnt, b.f, c.num, c.cnt, c.f); }//获取最大值
inline void Getmin(Num a,Num b,Num &c){ getmin(a.num, a.cnt, a.f, b.num, b.cnt, b.f, c.num, c.cnt, c.f); }//获取最小值
inline bool IsMax(Num a, Num b) { return ismax(a.num, a.cnt, a.f, b.num, b.cnt, b.f); }//判断a是不是最大
inline bool IsMin(Num a, Num b) { return ismin(a.num, a.cnt, a.f, b.num, b.cnt, b.f); }//判断a是不是最小
inline bool IsMaxNum(Num a,int x){Num b;CopyNum(b,x);return IsMax(a,b);}
inline bool IsMinNum(Num a,int x){Num b;CopyNum(b,x);return IsMin(a,b);}
inline void Add(Num a, Num b, Num &c) {//有符号高精度加
	if (a.f < 0 && b.f>0) _minus(b.num, b.cnt, a.num, a.cnt, c.num, c.cnt, c.f);
	else if (a.f > 0 && b.f < 0) _minus(a.num, a.cnt, b.num, b.cnt, c.num, c.cnt, c.f);
	else { c.f = a.f; add(a.num, a.cnt, b.num, b.cnt, c.num, c.cnt); }
}
inline void Minus(Num a, Num b, Num &c) {
	if (b.f < 0 && a.f>0) { c.f = 1; add(a.num, a.cnt, b.num, b.cnt, c.num, c.cnt); }
	else if (a.f < 0 && b.f>0) { c.f = -1; add(a.num, a.cnt, b.num, b.cnt, c.num, c.cnt); }
	else if (a.f > 0 && b.f > 0) _minus(a.num, a.cnt, b.num, b.cnt, c.num, c.cnt, c.f);
	else if (a.f < 0 && b.f < 0) _minus(b.num, b.cnt, a.num, a.cnt, c.num, c.cnt, c.f);
}
inline void AddNum(Num &a,int x){Num b,c;Init(c);CopyNum(b,x);Add(a,b,c);Copy(c,a);}
#define M 250005
struct Edge{Num v,w,next;}edge[M<<1];
Num head[M<<1],ce;
inline void adde(Num u,Num v,Num w){
	AddNum(ce,1);
	edge[GetNum(ce)].v=v;edge[GetNum(ce)].w=w;edge[GetNum(ce)].next=head[GetNum(u)];
	head[GetNum(u)]=ce;
//	cout<<GetNum(ce)<<' ';Write(u),Write(v),Write(w),Write(edge[GetNum(ce)].next);cout<<endl;
}
Num n,m,root;
Num dis[10005];bool vis[10005];
inline void SPFA(Num x){
	Num inf;CopyNum(inf,2147483647);Num j;Init(j);
	for(CopyNum(j,1);IsMin(j,n);AddNum(j,1)){
		dis[GetNum(j)]=inf;
		vis[GetNum(j)]=false;
	}
	CopyNum(dis[GetNum(x)],0);
	vis[GetNum(x)]=true;
	queue<Num> q;
	q.push(x);
	while(!q.empty()){
		Num u=q.front();q.pop();
		vis[GetNum(u)]=false;
		Num i=head[GetNum(u)];
		while(!IsMinNum(i,0)){
			Num v=edge[GetNum(i)].v;
			Num w=edge[GetNum(i)].w;
			Num val;Add(dis[GetNum(u)],w,val);
			if((!IsMin(dis[GetNum(v)],val)){
				dis[GetNum(v)]=val;
				if(!vis[GetNum(v)]){
					vis[GetNum(v)]=true;
					q.push(v);
				}
			}i=edge[GetNum(i)].next;
		}
	}
	for(CopyNum(j,1);IsMin(j,n);AddNum(j,1))
		Write(dis[GetNum(j)]);
}
inline void work(){
	Read(n),Read(m);Read(root);
	Num i;CopyNum(i,1);CopyNum(ce,0);
	for(Num u,v,w;IsMin(i,m);AddNum(i,1)){
		Read(u);Read(v);Read(w);
		adde(u,v,w);
	}
	SPFA(root);
} 
signed main() { work(); return 0; }
2023/8/18 10:47
加载中...