单源最短路板子题但是边权高精,调了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; }