LeetCode 847. Shortest Path Visiting All Nodes

题目链接:https://leetcode.com/problems/shortest-path-visiting-all-nodes/

题意:已知一条无向图,问经过所有点的最短路径是多长,边权都为1,每个点可能经过多次。

这道题写的时候想简单了,把它当成树的直径来做了,求出一条最长路径len(len上的点只经过一次),2*(点数-1)-len即为答案,竟然过了,后来看了看讨论区发现这不是正解,而且我也没办法证明,感觉是蒙对的。贴下代码:

class Solution {
public:
	void dfs(bool &f,int x, int sum, vector<vector<int>>& graph, int &ans, int vis[]) {
		if (f)
			return ;
		if (sum == graph.size()-1) {  //不加这个剪枝还会TLE,加了以后快的飞起,因为存在全连接图
			f = 1;
			ans = sum;
			return ;
		}
		vis[x] = 1;
		for (int i = 0;i < graph[x].size();i++) {
			if (vis[graph[x][i]] == 0) {
				dfs( f,graph[x][i], sum + 1, graph, ans, vis);
				vis[graph[x][i]] = 0;
			}
		}
		ans = max(sum, ans);   //ans为图中的最长路径(路径上的点只经过一次)
	}
	int shortestPathLength(vector<vector<int>>& graph) {
		if (graph[0].size() == 0)
			return 0;
		int vis[15];
		memset(vis, 0, sizeof(vis));
		int ans = 0;
		bool f = 0;
		for (int i = graph.size()-1;i>=0&&!f;i--) {
			memset(vis, 0, sizeof(vis));
			dfs(f,i, 0, graph, ans, vis);
		}

		cout << ans << -1 << endl;
		return (graph.size() - 1) * 2 - ans;
	}
}; 

正解应该是状压dp:

 dp[i][j]表示当前在第i个节点,且已经走过的节点集合为j用二进制表示时1的位置,从u到v,$dp[v][j|(1<<v)] = min(dp[v][j],dp[u][j]+1);$(dp[u][j]为在u点的状态),bfs不断更新即可

class Solution {
public:
	int shortestPathLength(vector<vector<int>>& graph) {
		vector<vector<int> > dp(graph.size(),vector<int>((1<<graph.size()),1e9) );
        queue<pair<int,int> > q;   //使用队列存储dp值
        for(int i=0;i<graph.size();i++){
            dp[i][1<<i]=0;
            q.push(make_pair(i,1<<i));
        }
        while(!q.empty()){
            pair p = q.front();
            q.pop();
            for(int i=0;i<graph[p.first].size();i++){
                int v=graph[p.first][i];
                if(dp[v][p.second|(1<<v)]>dp[p.first][p.second]+1){  //比当前优则入队
                    dp[v][p.second|(1<<v)] = dp[p.first][p.second]+1;
                    q.push(make_pair(v,p.second|(1<<v)));
                }
            }
        }
        int ans=1e9;
        for(int i=0;i<graph.size();i++)
            ans=min(ans,dp[i][(1<<graph.size())-1]);
        return ans;
	}
};

  

posted @ 2019-05-28 09:05  dlutjwh  阅读(134)  评论(0编辑  收藏  举报