求助__int128
查看原帖
求助__int128
609565
OtterZ楼主2023/4/2 14:47

本人将自己的 AC 代码(如下):

#include<cstdio>
#include<queue>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,k,s,t,u,v,w,wh[101],dist[101],ans=0x3f3f3f3f;
bool vis[101],lp=false;
bool tcp[101][101];
struct edge{
	int ed,len;
	
};
bool operator<(edge mk,edge k){
		return mk.len>k.len;
	}
vector<edge>e[101],el[101];
priority_queue<edge>q;
void Dijkstra(int begin){
	memset(dist,0x3f3f3f3f,sizeof(dist));
	memset(vis,false,sizeof(vis));
	q.push(edge{begin,0});
	dist[begin]=0;
	while(!q.empty()){
		edge d=q.top();
		q.pop();
		if(vis[d.ed])continue;
		vis[d.ed]=true;
		for(int i=0;e[d.ed].size()>i;i++){
			if(dist[e[d.ed][i].ed]>dist[d.ed]+e[d.ed][i].len){
				dist[e[d.ed][i].ed]=dist[d.ed]+e[d.ed][i].len;
				q.push(edge{e[d.ed][i].ed,dist[e[d.ed][i].ed]});
			}
		}
	}
}
inline void srh(int p,int d,int dt[]){
    if(!vis[p]||(lp&&dist[p]+d>=ans))return;
    if(p==t){
        ans=d;
        lp=true;
        return;
    }
    dt[wh[p]]++;
    for(int i=0;el[p].size()>i;i++){
        for(int j=1;j<=k;j++){
            if(tcp[wh[el[p][i].ed]][j]&&dt[j]!=0)goto end;
        }
		if(!(!vis[el[p][i].ed]||(lp&&dist[el[p][i].ed]+d+el[p][i].len>=ans))){
			srh(el[p][i].ed,d+el[p][i].len,dt);
		}
        end:continue;
	}
    dt[wh[p]]--;
}
int r[101];
int main(){
	scanf("%d%d%d%d%d",&n,&k,&m,&s,&t);
	for(int i=1;i<=n;i++){
	    scanf("%d",&wh[i]);
	}
	for(int i=1;i<=k;i++){
	    for(int j=1;j<=k;j++){
	        scanf("%d",&u);
	        if(j==i)u=1;
	        tcp[i][j]=u;
	    }
	}
    if(tcp[wh[t]][wh[s]]){
        printf("-1");
        return 0;
    }
	for(int i=1;m>=i;i++){
		scanf("%d%d%d",&u,&v,&w);
        if(tcp[wh[v]][wh[u]])continue;
		e[v].push_back(edge{u,w});
		el[u].push_back(edge{v,w});
	}
	Dijkstra(t);
	srh(s,0,r);
	if(lp)printf("%d",ans);
	else printf("-1");
	return 0;
}

改为如下:

#include<cstdio>
#include<queue>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,k,s,t,u,v,w,wh[101],dist[101],ans=0x3f3f3f3f;
__int128 tcp[101];
bool vis[101],lp=false;
struct edge{
	int ed,len;
	
};
bool operator<(edge mk,edge k){
		return mk.len>k.len;
	}
vector<edge>e[101],el[101];
priority_queue<edge>q;
void Dijkstra(int begin){
	memset(dist,0x3f3f3f3f,sizeof(dist));
	memset(vis,false,sizeof(vis));
	q.push(edge{begin,0});
	dist[begin]=0;
	while(!q.empty()){
		edge d=q.top();
		q.pop();
		if(vis[d.ed])continue;
		vis[d.ed]=true;
		for(unsigned i=0;i<e[d.ed].size();i++){
			if(dist[e[d.ed][i].ed]>dist[d.ed]+e[d.ed][i].len){
				dist[e[d.ed][i].ed]=dist[d.ed]+e[d.ed][i].len;
				q.push(edge{e[d.ed][i].ed,dist[e[d.ed][i].ed]});
			}
		}
	}
}
inline void srh(register int p,register int d,register __int128 sl){
    if(!vis[p]||(lp&&dist[p]+d>=ans))return;
    if(p==t){
        ans=d;
        lp=true;
        return;
    }
    sl+=((__int128)1<<k-wh[p]);
    for(register unsigned i=0;el[p].size()>i;i++){
		if((tcp[wh[el[p][i].ed]]&sl)==0){
			srh(el[p][i].ed,d+el[p][i].len,sl);
		}
	}
}
int main(){
	scanf("%d%d%d%d%d",&n,&k,&m,&s,&t);
	for(register int i=1;i<=n;i++){
	    scanf("%d",&wh[i]);
	}
	for(int i=1;i<=k;i++){
	    for(int j=1;j<=k;j++){
	        scanf("%d",&u);
	        if(j==i)u=1;
	        tcp[i]=tcp[i]*2+u;
	    }
	}
	for(int i=1;m>=i;i++){
		scanf("%d%d%d",&u,&v,&w);
		e[v].push_back(edge{u,w});
		el[u].push_back(edge{v,w});
	}
	Dijkstra(t);
	srh(s,0,(__int128)0);
	if(lp)printf("%d",ans);
	else printf("-1");
	return 0;
}

即改为利用 __int128 进行位运算,本以为可以更快,结果反而 TLE 92pts,想知道是为什么。

2023/4/2 14:47
加载中...