Cod sursa(job #2774308)

Utilizator traiandobrinDobrin Traian traiandobrin Data 11 septembrie 2021 00:23:59
Problema Ubuntzei Scor 70
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.46 kb
#include <fstream>
#include <vector>
#include <queue>
#include <bitset>
#define f first
#define s second
using namespace std;
ifstream cin("ubuntzei.in");
ofstream cout("ubuntzei.out");
const int nmax=2005;
bitset <nmax> freq;
int loc[nmax],dist[nmax][nmax],dp[20][32773],n,m,k,act;
vector <pair<int,int> > g[nmax];
vector <vector <int> > unite;
struct cmp
{
    bool operator()(int a,int b)
    {
        return dist[act][a]<dist[act][b];
    }
};
struct imaginar
{
    int pos,msk,cost;
};
struct cmp2
{
    bool operator()(imaginar a,imaginar b)
    {
        return a.pos<b.pos;
    }
};
priority_queue <int,vector<int>,cmp> q;
priority_queue <imaginar,vector<imaginar>,cmp2> v;
void dijkstra(int uwu)
{
    q.push(uwu);
    act=uwu;
    freq[uwu]=1;
    while(!q.empty())
    {
        int node=q.top();
        q.pop();
        if(node!=uwu)
            freq[node]=0;
        for(int i=0; i!=g[node].size(); ++i)
        {
            int new_node=g[node][i].f;
            if((dist[act][node]+g[node][i].s<dist[act][new_node]||dist[act][new_node]==0))
            {   if(new_node!=uwu)
                dist[act][new_node]=dist[act][node]+g[node][i].s;
                if(freq[new_node]==0)
                {
                    q.push(new_node);
                    freq[new_node]=1;
                }
            }
        }
    }
}
int nob(int x)
{
    int cnt=0;
    while(x)
    {
        cnt+=x%2;
        x/=2;
    }
    return cnt;
}
int main()
{
    cin>>n>>m>>k;
    unite = vector <vector <int> >(4, vector <int>(1 << k+1));
    for(int i=1; i<=k; ++i)
        cin>>loc[i];
    for(int i=1; i<=m; ++i)
    {
        int a,b,c;
        cin>>a>>b>>c;
        g[a].push_back({b,c});
        g[b].push_back({a,c});
    }
    loc[k+1]=n;
    for(int i=1; i<=k+1; ++i){
        dijkstra(loc[i]);
    for(int j=0;j<=n;++j)
        freq[j]=0;
    }
    for(int i=1; i<=k+1; ++i)
        dp[i][1<<(i-1)]=dist[loc[i]][1];
    for(int nrb=2; nrb<=k; ++nrb)
    {
        for(int msk=1; msk<=1<<k; ++msk)
            if(nob(msk)==nrb-1)
            {
                for(int j=1; j<=k; ++j){
                        int x=msk&(1<<(j-1));
                    if(x==0)
                    {
                        int val=1e9;
                        for(int i=1; i<=k; ++i){
                                int y=msk&(1<<(i-1));
                            if(y)
                                val=min(val,dist[loc[i]][loc[j]]+dp[i][msk]);}
                                    if(dp[j][msk+(1<<(j-1))]==0||dp[j][msk+(1<<(j-1))]>val)
                                        dp[j][msk+(1<<(j-1))]=val;
                    }}
            }
    }
    int val=1e9;
    if(k)
    for(int i=1; i<=k; ++i)
        val=min(val,dist[loc[i]][loc[k+1]]+dp[i][(1<<k)-1]);
        else
        {
            dijkstra(1);
            val=dist[1][n];
        }
            cout<<val;
    /* v.push({1,0,0});
     while(!v.empty())
     {
         imaginar node=v.top();
         v.pop();
         for(int i=0;i<=(1<<k);++i)
         {

             if((dist[act][node]+g[node][i].s<dist[act][new_node]||dist[act][new_node]==0))
             {
                 dist[act][new_node]==dist[act][node]+g[node][i].s;
                 if(f[new_node]==0)
                 {
                     v.push(new_node);
                     freq[new_node]=1;
                 }
             }
         }
     }*/
    return 0;
}