http://acm.hdu.edu.cn/showproblem.php?pid=2433
这个问题因为路径都是1,所以可以用bfs遍历
可以看这几篇文章讲解:
http://blog.csdn.net/panyanyany/article/details/7215069
(这篇代码非常清晰,而且效率很高)
http://www.cppblog.com/keroro/archive/2013/05/27/200622.html?opt=admin
1 #include <cstdio> 2 #include <queue> 3 #include <vector> 4 using namespace std; 5 6 #define MEM(a,v) memset (a,v,sizeof(a)) 7 // a for address, v for value 8 9 #define max(x,y) ((x)>(y)?(x):(y)) 10 #define max(x,y) ((x)>(y)?(x):(y)) 11 12 const int L = 1010; 13 const int INF = 1<<27; 14 15 bool used[L], bCnet, bInit ; 16 int n, m ; 17 int dist[L], map[L][L], sum_d[L], pre[L][L]; 18 19 20 //边表 21 struct Edge 22 { 23 int u,v; 24 }; 25 26 Edge e[30*L]; 27 28 29 int bfs(int beg) 30 { 31 MEM(used,false); 32 MEM(dist,0); 33 34 used[beg] = true; 35 36 queue<int> q; 37 q.push(beg); 38 39 int i; 40 41 while(!q.empty()) 42 { 43 int t = q.front(); 44 q.pop(); 45 for(i = 1;i<=n;i++) 46 { 47 if(!used[i] && map[t][i]) 48 { 49 used[i] = true; 50 dist[i] = dist[t]+1; 51 52 //初始化 bInit =true 53 //初始化后 bfs = false 54 if(bInit) 55 pre[beg][i] = t; 56 //pre储存的是beg树里面,i的上一个元素 57 //这样只需判断pre[x][u] ==v 和pre[x][v] == u 58 //就可以知道x树里面有没有uv边 59 60 q.push(i); 61 } 62 } 63 } 64 65 int sum = 0; 66 67 68 //求出点beg到各边的距离和 69 // 从 beg+1 开始 和从 1 开始,效果差不多 70 for(i = beg+1;i<=n;i++) 71 { 72 if(!dist[n]) 73 return INF; 74 else 75 sum+=dist[i]; 76 } 77 return sum; 78 79 } 80 81 82 83 int main() 84 { 85 int i,j; 86 87 int u,v,sum,res; 88 89 while(~scanf("%d%d",&n,&m)) 90 { 91 MEM(map,0); 92 MEM(pre,0); 93 94 for(i = 1;i<=m;i++) 95 { 96 scanf("%d%d",&u,&v); 97 map[u][v] = ++map[v][u]; 98 99 //如果有重复边的话,map为2 100 101 e[i].u = v; 102 e[i].v = u; 103 } 104 105 sum = 0; 106 bInit = true; 107 bCnet = true; 108 109 110 //求出每个点到其他点的距离和 111 for(i = 1;i<=n;i++) 112 { 113 sum_d[i] = bfs(i); 114 sum+=sum_d[i]; 115 116 if(sum>=INF) 117 { 118 bCnet = false; 119 break; 120 } 121 } 122 123 bInit = false; 124 125 126 //删除边 127 for(i = 1;i<=m;i++) 128 { 129 //uv为删除的边 130 u = e[i].u; 131 v = e[i].v; 132 133 // map[u][v] 判断有无重边,可以优化300多MS 134 if(bCnet && map[u][v] == 1) 135 { 136 res = 0; 137 for(j = 1;j<=n;j++) 138 { 139 //j树里不存在删除的边 140 // 最重要的剪枝,否则直接超时 141 if(pre[j][u] != v && pre[j][v] !=u) 142 { 143 res += sum_d[j]; 144 } 145 else 146 { 147 //存在uv边,j树重新bfs 148 --map[u][v]; 149 --map[v][u]; 150 res += bfs(j); 151 ++map[u][v]; 152 ++map[v][u]; 153 154 if(res >= INF) 155 break; 156 157 } 158 159 } 160 161 162 163 } 164 else 165 res=sum; 166 167 if(res >= INF) 168 puts("INF"); 169 else 170 printf("%d\n",res*2); 171 172 } 173 174 175 } 176 177 return 0; 178 }
时间: 2024-11-05 20:21:02