2 条题解

  • 0
    @ 2025-10-8 17:06:38
    #include <bits/stdc++.h>
    using namespace std;
    typedef pair<int, int> PII;
    const int N = 105, INF = 0x3f3f3f3f;
    vector<int> G[N];
    int n, m, a[105], b[15], dp[N][1 << 10];
    bool vis[N];
    
    int id(int i, int j) { return (i - 1) * m + j; }
    
    void dijkstra(int s) {
        memset(vis, 0, sizeof(vis));
        priority_queue<PII, vector<PII>, greater<PII>> q;
        for (int i = 1; i <= n * m; 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 (int y : G[x]) {
                if (dp[y][s] > dp[x][s] + a[y]) {
                    dp[y][s] = dp[x][s] + a[y];
                    q.push({dp[y][s], y});
                }
            }
        }
    }
    
    int main() {
        scanf("%d%d", &n, &m);
        int k = 0;
        memset(dp, 0x3f, sizeof(dp));
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= m; j++) {
                int p = id(i, j);
                scanf("%d", &a[p]);
                if (a[p] == 0) {
                    b[++k] = p;
                    dp[b[k]][1 << (k - 1)] = 0;
                }
                if (i > 1) {
                    int x = id(i - 1, j), y = id(i, j);
                    G[x].push_back(y);
                    G[y].push_back(x);
                }
                if (j > 1) {
                    int x = id(i, j - 1), y = id(i, j);
                    G[x].push_back(y);
                    G[y].push_back(x);
                }
            }
    
        for (int S = 1; S < (1 << k); S++) {
            for (int s = S - 1; s; s = S & (s - 1))
                for (int i = 1; i <= n * m; i++)
                    dp[i][S] = min(dp[i][S], dp[i][s] + dp[i][S ^ s] - a[i]);
            dijkstra(S);
        }
        printf("%d\n", dp[b[1]][(1 << k) - 1]);
        return 0;
    }
    
    • 0
      @ 2025-10-8 17:06:31
      #include <bits/stdc++.h>
      using namespace std;
      typedef pair<int,int> PII;
      const int N=105, INF=0x3f3f3f3f;
      vector<int>G[N];
      using namespace std;  
      int n,m,a[105],b[15],dp[N][1<<10];bool vis[N]; 
      int id(int i,int j){ return (i-1)*m+j;} 
      void dijkstra(int s)
      {
      	memset(vis, 0, sizeof(vis));
          priority_queue<PII,vector<PII>,greater<PII>> q;
      	for(int i=1;i<=n*m;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(int y:G[x])
      		{
      			if(dp[y][ s ]>dp[x][ s ]+a[y])
      			{
      				dp[y][ s ]=dp[x][ s ]+a[y];
      				q.push({dp[y][ s ],y});
      			}
      		}
      	}
      }
        
      int main()  
      {   
          scanf("%d%d",&n,&m);
          int k=0;
          memset(dp,0x3f,sizeof(dp));
          for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
          {
              int p=id(i,j);
              scanf("%d",&a[p]);
              if(a[p]==0)
              {
                  b[++k]=p;
                  dp[b[k]][1<<(k-1)]=0;
              }
              if(i>1)
              {
                  int x=id(i-1,j),y=id(i,j);
                  G[x].push_back(y);
                  G[y].push_back(x);
              }
              if(j>1)
              {
                  int x=id(i,j-1),y=id(i,j);
                  G[x].push_back(y);
                  G[y].push_back(x);
              }
          }
      
      	for(int S=1;S<(1<<k);S++)
      	{
      		for(int s=S-1;s;s=S&(s-1))
      			for(int i=1;i<=n*m;i++)
                      dp[i][ S ]=min(dp[i][ S ],dp[i][ s ]+dp[i][S^s]-a[i]);
      		dijkstra(S);
      	}
      	printf("%d\n",dp[b[1]][(1<<k)-1]);
      	return 0;
      }
      • 1

      *【状压DP:最小斯坦纳树】游览计划[WC2008简化版]

      信息

      ID
      4260
      时间
      1000ms
      内存
      256MiB
      难度
      9
      标签
      递交数
      9
      已通过
      4
      上传者