CF1842D Tenzing and His Animal Friends 题解
很好的一道图论建模题。
看到
如果
现在考虑有解时怎么构造解。两种想法,一种是一开始能玩的全部一起玩(即第一次游戏最大化
一开始集合里只有
实现过程可以使用优先队列维护。
放代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int,int> pii;
main(){
ios::sync_with_stdio(false);
int n,m,c=0; cin>>n>>m;
vector<vector<int> > d(n,vector<int>(n,2e18));
vector<bool> b(n);
for(int i=0;i<n;i++)d[i][i]=0; // 初始化
for(int i=0;i<m;i++){
int u,v,w; cin>>u>>v>>w;
d[u-1][v-1]=d[v-1][u-1]=w;
} // 建边
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
for(int k=0;k<n;k++)
if(i!=j&&i!=k&&j!=k)
d[j][k]=min(d[j][k],d[j][i]+d[i][k]);
// Floyd 算法预处理最短路
if(d[0][n-1]==2e18)cout<<"inf\n"; // 可以玩无限久
else{
vector<pair<vector<bool>,int> > r;
priority_queue<pii,vector<pii>,greater<pii> > q;
for(int i=0;i<n;i++)
if(d[0][i])q.emplace(d[0][i],i);
else b[i]=true;
while(!q.empty()&&!b[n-1]){
int u=q.top().second; q.pop();
if(b[u])continue;
r.emplace_back(b,d[0][u]-c),c=d[0][u];
for(int i=1;i<n;i++)
if(d[0][i]==d[0][u])b[i]=true; // 打标记
} // 每次取出剩下的中与 1 最短路最小的几个数
cout<<d[0][n-1]<<' '<<r.size()<<endl;
for(auto [x,y]:r){
for(bool i:x)cout<<i;
cout<<' '<<y<<endl;
}
}
return 0;
}