E - Magical Ornament
题意:
给你m条边。
给你k个点,这k个点要都走到,
且最后根据m条边形成一个最短的串。
思路:
应该是按照每k个点求最长路。
之后dp(状压)。
AC1
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
int N,M;
vector<int>G[1<<17];
int K;
int C[17];
int E[17][17];
int dp[1<<17][17];
main()
{
cin>>N>>M;
for(int i=0;i<M;i++)
{
int a,b;
cin>>a>>b;
a--,b--;
G[a].push_back(b);
G[b].push_back(a);
}
cin>>K;
for(int i=0;i<K;i++)
{
cin>>C[i];
C[i]--;
}
for(int i=0;i<K;i++)
{
vector<int>now(N,1e9);
queue<int>P;
now[C[i]]=0;
P.push(C[i]);
while(!P.empty())
{
int u=P.front();P.pop();
for(int v:G[u])if(now[v]>now[u]+1)
{
now[v]=now[u]+1;
P.push(v);
}
}
for(int j=0;j<K;j++)
{
E[i][j]=now[C[j]];
}
}
for(int i=0;i<1<<K;i++)for(int j=0;j<K;j++)dp[i][j]=1e9;
for(int i=0;i<K;i++)dp[1<<i][i]=1;
for(int i=1;i<1<<K;i++)for(int j=0;j<K;j++)if(dp[i][j]<(int)1e9)
{
for(int k=0;k<K;k++)if(E[j][k]<(int)1e9)
{
dp[i|1<<k][k]=min(dp[i|1<<k][k],dp[i][j]+E[j][k]);
}
}
int ans=1e9;
for(int i=0;i<K;i++)ans=min(ans,dp[(1<<K)-1][i]);
if(ans<(int)1e9)cout<<ans<<endl;
else cout<<-1<<endl;
}
AC2
#include <bits/stdc++.h>
using namespace std;
const int INF = 1000000000;
int main(){
int N, M;
cin >> N >> M;
vector<vector<int>> E(N);
for (int i = 0; i < M; i++){
int A, B;
cin >> A >> B;
A--;
B--;
E[A].push_back(B);
E[B].push_back(A);
}
int K;
cin >> K;
vector<int> C(K);
for (int i = 0; i < K; i++){
cin >> C[i];
C[i]--;
}
vector<vector<int>> cnt(K, vector<int>(K));
for (int i = 0; i < K; i++){
vector<int> d(N, -1);
d[C[i]] = 0;
queue<int> Q;
Q.push(C[i]);
while (!Q.empty()){
int v = Q.front();
Q.pop();
for (int w : E[v]){
if (d[w] == -1){
d[w] = d[v] + 1;
Q.push(w);
}
}
}
for (int j = 0; j < K; j++){
cnt[i][j] = d[C[j]];
}
}
vector<vector<int>> dp(1 << K, vector<int>(K, INF));
for (int i = 0; i < K; i++){
dp[1 << i][i] = 1;
}
for (int i = 1; i < (1 << K); i++){
for (int j = 0; j < K; j++){
if (dp[i][j] != INF){
for (int k = 0; k < K; k++){
if (!(i >> k & 1)){
if (cnt[j][k] != -1){
int i2 = i + (1 << k);
dp[i2][k] = min(dp[i2][k], dp[i][j] + cnt[j][k]);
}
}
}
}
}
}
int ans = INF;
for (int i = 0; i < K; i++){
ans = min(ans, dp[(1 << K) - 1][i]);
}
if (ans == INF){
cout << -1 << endl;
} else {
cout << ans << endl;
}
}
AC3
//#define _GLIBCXX_DEBUG
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define lfs cout<<fixed<<setprecision(10)
#define ALL(a) (a).begin(),(a).end()
#define ALLR(a) (a).rbegin(),(a).rend()
#define spa << " " <<
#define fi first
#define se second
#define MP make_pair
#define MT make_tuple
#define PB push_back
#define EB emplace_back
#define rep(i,n,m) for(ll i = (n); i < (ll)(m); i++)
#define rrep(i,n,m) for(ll i = (ll)(m) - 1; i >= (ll)(n); i--)
using ll = long long;
using ld = long double;
const ll MOD1 = 1e9+7;
const ll MOD9 = 998244353;
const ll INF = 1e18;
using P = pair<ll, ll>;
template<typename T1, typename T2>
bool chmin(T1 &a,T2 b){if(a>b){a=b;return true;}else return false;}
template<typename T1, typename T2>
bool chmax(T1 &a,T2 b){if(a<b){a=b;return true;}else return false;}
ll median(ll a,ll b, ll c){return a+b+c-max({a,b,c})-min({a,b,c});}
void ans1(bool x){if(x) cout<<"Yes"<<endl;else cout<<"No"<<endl;}
void ans2(bool x){if(x) cout<<"YES"<<endl;else cout<<"NO"<<endl;}
void ans3(bool x){if(x) cout<<"Yay!"<<endl;else cout<<":("<<endl;}
template<typename T1,typename T2>
void ans(bool x,T1 y,T2 z){if(x)cout<<y<<endl;else cout<<z<<endl;}
template<typename T>
void debug(vector<vector<T>>&v,ll h,ll w){for(ll i=0;i<h;i++)
{cout<<v[i][0];for(ll j=1;j<w;j++)cout spa v[i][j];cout<<endl;}};
void debug(vector<string>&v,ll h,ll w){for(ll i=0;i<h;i++)
{for(ll j=0;j<w;j++)cout<<v[i][j];cout<<endl;}};
template<typename T>
void debug(vector<T>&v,ll n){if(n!=0)cout<<v[0];
for(ll i=1;i<n;i++)cout spa v[i];cout<<endl;};
template<typename T>
vector<vector<T>>vec(ll x, ll y, T w){
vector<vector<T>>v(x,vector<T>(y,w));return v;}
ll gcd(ll x,ll y){ll r;while(y!=0&&(r=x%y)!=0){x=y;y=r;}return y==0?x:y;}
vector<ll>dx={1,-1,0,0,1,1,-1,-1};
vector<ll>dy={0,0,1,-1,1,-1,1,-1};
template<typename T>
vector<T> make_v(size_t a,T b){return vector<T>(a,b);}
template<typename... Ts>
auto make_v(size_t a,Ts... ts){
return vector<decltype(make_v(ts...))>(a,make_v(ts...));
}
template<typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2>&p){
return os << p.first << " " << p.second;
}
//mt19937 mt(chrono::steady_clock::now().time_since_epoch().count());
vector<ll>dist(200001);
void bfs(ll k,vector<vector<ll>>&g){
queue<P> q;
ll n=g.size();
q.emplace(k,0);
fill(dist.begin(),dist.begin()+n,INF);
while(!q.empty()){
ll x=q.front().fi;
ll len=q.front().se;
if(dist[x]==INF){
dist[x]=len;
for(ll i=0;i<g[x].size();i++){
q.emplace(g[x][i],len+1);
}
}
q.pop();
}
}
int main(){
cin.tie(nullptr);
ios_base::sync_with_stdio(false);
ll res=0,buf=0;
bool judge = true;
ll n,m;cin>>n>>m;
vector<vector<ll>>g(n);
rep(i,0,m){
ll u,v;cin>>u>>v;u--;v--;
g[u].PB(v);
g[v].PB(u);
}
ll k;cin>>k;
vector<ll>t(k);
rep(i,0,k)cin>>t[i],t[i]--;
auto d=vec(k,k,0LL);
rep(i,0,k){
bfs(t[i],g);
rep(j,0,k)d[i][j]=dist[t[j]];
}
auto dp=vec(1<<k,k,INF);
rep(i,0,k)dp[1<<i][i]=0;
rep(i,0,1<<k){
rep(j,0,k){
if(dp[i][j]==INF)continue;
rep(o,0,k){
if(i&1<<o)continue;
chmin(dp[i|1<<o][o],dp[i][j]+d[j][o]);
}
}
}
ll ret=*min_element(ALL(dp[(1<<k)-1]));
ans(ret==INF,-1,ret+1);
return 0;
}