2 条题解

  • 0
    @ 2025-10-8 16:51:54
    #include <bits/stdc++.h>
    using namespace std;
    typedef pair<int, int> PII;
    const int N = 110, INF = 0x3f3f3f3f;
    vector<PII> G[N];
    int n, dp[N][1 << 10], vis[N], a[N];
    
    void dijkstra(int s) {
        memset(vis, 0, sizeof(vis));
        priority_queue<PII, vector<PII>, greater<PII>> q;
        for (int i = 1; i <= n; i++) if (dp[i][s] != INF) q.push({dp[i][s], i});
        while (!q.empty()) {
            int x = q.top().second; q.pop();
            if (vis[x]) continue;
            vis[x] = 1;
            for (auto i : G[x]) {
                int y = i.first, w = i.second;
                if (dp[y][s] > dp[x][s] + w) {
                    dp[y][s] = dp[x][s] + w;
                    q.push({dp[y][s], y});
                }
            }
        }
    }
    
    int main() {
        int m, k; scanf("%d%d%d", &n, &m, &k);
        for (int i = 1, x, y, w; i <= m; i++) {
            scanf("%d%d%d", &x, &y, &w);
            G[x].push_back({y, w});
            G[y].push_back({x, w});
        }
        memset(dp, 0x3f, sizeof(dp));
        for (int i = 1; i <= k; i++) {
            scanf("%d", &a[i]);
            dp[a[i]][1 << (i - 1)] = 0;
        }
        for (int S = 1; S < (1 << k); S++) { // 枚举给定点集的所有非空子集S
            for (int s = S - 1; s; s = S & (s - 1)) { // 枚举S的所有非空子集s
                for (int i = 1; i <= n; i++)
                    dp[i][S] = min(dp[i][S], dp[i][s] + dp[i][S ^ s]);
            }
            dijkstra(S);
        }
        printf("%d\n", dp[a[1]][(1 << k) - 1]);
        return 0;
    }
    
    • 0
      @ 2025-10-8 16:51:46
      #include <bits/stdc++.h>
      using namespace std;
      typedef pair<int,int> PII;
      const int N=110, INF=0x3f3f3f3f;
      vector<PII>G[N];
      int n,dp[N][1<<10],vis[N],a[N];
      void dijkstra(int s)
      {
      	memset(vis, 0, sizeof(vis));
          priority_queue<PII,vector<PII>,greater<PII>> q;
      	for(int i=1;i<=n;i++)if(dp[i][ s ]!=INF)q.push({dp[i][ s ],i});
      	while(!q.empty())
      	{
      		int x=q.top().second;q.pop();
      		if(vis[x])continue;
      		vis[x]=1;
      		for(auto i:G[x])
      		{
      			int y=i.first,w=i.second;
      			if(dp[y][ s ]>dp[x][ s ]+w)
      			{
      				dp[y][ s ]=dp[x][ s ]+w;
      				q.push({dp[y][ s ],y});
      			}
      		}
      	}
      }
      
      int main()
      {
      	int m,k;scanf("%d%d%d",&n,&m,&k);
      	for(int i=1,x,y,w;i<=m;i++)
      	{
      		scanf("%d%d%d",&x,&y,&w);
      		G[x].push_back({y,w});
      		G[y].push_back({x,w});
      	}
      	memset(dp,0x3f,sizeof(dp));
      	for(int i=1;i<=k;i++)
      	{
      		scanf("%d",&a[i]);
      		dp[a[i]][1<<(i-1)]=0;
      	}
      	for(int S=1;S<(1<<k);S++)//枚举给定点集的所有非空子集S
      	{
      		for(int s=S-1;s;s=S&(s-1))  // 枚举S的所有非空子集s
      			for(int i=1;i<=n;i++)
                      dp[i][ S ]=min(dp[i][ S ],dp[i][ s ]+dp[i][S^s]);
      		dijkstra(S);
      	}
      	printf("%d\n",dp[a[1]][(1<<k)-1]);
      	return 0;
      }
      • 1

      *【状压DP:最小斯坦纳树】最小斯坦纳树[LOJ187]

      信息

      ID
      719
      时间
      1000ms
      内存
      256MiB
      难度
      8
      标签
      (无)
      递交数
      14
      已通过
      9
      上传者