wannafly挑战赛12E题

题解:因为gcd(a,b)最大就只有1W所以我们可以维护一下到达0~gcd(a,b)-1需要的最小代价,我们可以用spfa求最短路径那样求因为我们加一个s[i]就变到另外一个值就相当于路径的权值是v[i],接着我们跑完之后,当然我们同时维护如果代价相等的时候我们要取小子序列,最后维护完之后我们呢查找出来所有能到达的状态并且(i*10+v)%m==0的最小代价,然后我们从中选择子序列最小的一个串输出补上v即可

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<cstdio>
#include<cmath>
#include<set>
#include<map>
#include<cstdlib>
#include<ctime>
#include<stack>
using namespace std;
#define mes(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(i = a; i <= b; i++)
#define dec(i,a,b) for(i = b; i >= a; i--)
#define fi first
#define se second
#define ls rt<<1
#define rs rt<<1|1
#define mid (L+R)/2
#define lson ls,L,mid
#define rson rs,mid+1,R
typedef double db;
typedef long long int ll;
typedef pair<int,int> pii;
typedef unsigned long long ull;
const int mx = 1e5+5;
const ll inf = 1e15;
const int x_move[] = {1,-1,0,0,1,1,-1,-1};
const int y_move[] = {0,0,1,-1,1,-1,1,-1};
int n,m;
ll dis[mx];
string s[mx];
bool vis[mx];
vector<string>g;
struct node{
    int s,w;
    char str[2];
    bool operator<(const node &a)const{
        if(w!=a.w)  return w < a.w;
        else return s < a.s;
    }
}a[mx];
int gcd(int a,int b){
    return b == 0?a:gcd(b,a%b);
}
bool spfa(int u,int v){
    queue<int>q;
    g.clear();
    memset(vis,0,sizeof(vis));
    int p;
    for(int i = 0; i < m; i++)   dis[i] = inf;
    for(int i = 0; i < n; i++){
        if(a[i].s==u)
            dis[u%m]  = a[i].w,s[u%m] = a[i].str;
        if(a[i].s==v)
            p = i;
    }
    vis[u%m] = 1;
    q.push(u%m);
    while(!q.empty()){
        u = q.front();
        q.pop();
        vis[u] = 0;
        for(int i = 0; i < n; i++){
            int v = (u*10+a[i].s)%m;
            if(dis[v]>dis[u]+a[i].w){
                dis[v] = dis[u]+a[i].w;
                s[v] = s[u] + a[i].str;
                if(!vis[v]){
                    q.push(v);
                    vis[v] = 1;
                }
            }
            else if(dis[v]==dis[u]+a[i].w){
                string str = s[u]+a[i].str;
                if(s[v]<str)
                    s[v] = str;
                if(!vis[v]){
                    q.push(v);
                    vis[v] = 1;
                }
            }
        }
    }
    ll ans = inf;
    for(int i = 0; i < m; i++)
        if((i*10+v)%m==0)
            ans = min(ans,dis[i]);
    if(ans==inf)
        return true;
    for(int i = 0; i < m; i++)
        if((i*10+v)%m==0&&ans==dis[i]){
            s[i]+=a[p].str;
            g.push_back(s[i]);
        }
    sort(g.begin(),g.end());
    cout<<g[0]<<endl;
    return false;
}
int main(){
    int t,q,ca = 1;
    int x,y;
    while(scanf("%d%d%d",&x,&y,&n)!=EOF){
        m = gcd(x,y);
        for(int i = 0; i < n; i++){
            scanf("%d",&a[i].s);
            a[i].str[0] = a[i].s+'0';
        }
        for(int i = 0; i < n; i++)
            scanf("%d",&a[i].w);
        sort(a,a+n);
        int u,v;
        scanf("%d%d",&u,&v);
        if(u==v&&m==u){
            for(int i = 0; i < n; i++)
                if(a[i].s==v){
                    printf("%d\n",a[i].w);
                    break;
                }
            continue;
        }
        if(spfa(u,v))  
            puts("-1");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/a1325136367/article/details/79719289