UVA 539 - The Settlers of Catan 暴力 全排列

来源:互联网 发布:php获取p标签中的img 编辑:程序博客网 时间:2024/04/28 07:45
这道题目的意思就是在图上找到一条最长的路径


每条路径   不可能枚举25个数的全排列  肯定超时 


所以要在枚举的时候判断当前点和枚举的下一个点是否有边存在  且边没有被访问过




上面的思路好像有个bug    因为点是可以重复的  而且不知道这些点会出现几次   pass掉这种想法    
枚举点不行但是可以枚举边啊  边最多25条  哇 25!好大
但是一想  我们不用枚举每个全排列  只需要枚举可以构成路径的就行
不能构成路径的全排列不用管他  以他为基础的全排列也不用管
优化了非常多的时间  理论上是不会超时的  但还是要看实际情况
想着用上面的方法比较麻烦  所以用了下面的方法 DFS n便就OK了




找到一条最长的路径  DFS    但是DFS的时候怎么才能确保找到的路径是最长的???        


从每个点开始DFS一次   25个点  不会超时


思考怎么才能在DFS的时候去掉不是答案的分支   提高效率???


#include<cstdio>#include<cstring>using namespace std;const int maxn = 30;int G[maxn][maxn],vis[maxn][maxn];int MaxLength,n,m;void DFS(int i,int cur){    if(cur > MaxLength) MaxLength = cur;    for(int k = 0; k < n; k++)    {        if(G[i][k] == 1 && vis[i][k] != 1)        {            vis[i][k] = vis[k][i] = 1;            DFS(k,cur+1);            vis[i][k] = vis[k][i] = 0;        }    }}int main(){    #ifdef LOCAL    freopen("in.txt","r",stdin);    #endif // LOCAL    while(scanf("%d%d",&n,&m)&&n&&m)    {        int x,y;        memset(G,0,sizeof(G));        for(int i = 0; i < m; i++)        {            scanf("%d%d",&x,&y);            G[x][y] = G[y][x] = 1;        }        MaxLength = 0;        for(int i = 0; i < n; i++)        {            memset(vis,0,sizeof(vis));            DFS(i,0);        }        printf("%d\n",MaxLength);    }    return 0;}


0 0