标签:push struct span play while code res oca opened
1 #include <cstdio> 2 #include <queue> 3 #include <algorithm> 4 #define INF 0x3f3f3f3f 5 using namespace std; 6 7 const int maxn=1001; 8 vector<int> g[maxn]; 9 struct node 10 { 11 int num,dis; 12 }; 13 int n,m; 14 int cost[maxn][maxn],d[maxn]; 15 int ans; 16 17 bool operator<(const node& n1,const node& n2) 18 { 19 return n1.dis<n2.dis; 20 } 21 22 void dij() 23 { 24 fill(d+1,d+n+1,INF); 25 d[2]=0; 26 priority_queue<node> que; 27 que.push(node{2,0}); 28 while(!que.empty()) 29 { 30 int x=que.top().num; 31 que.pop(); 32 for(int i=0;i<g[x].size();i++) 33 { 34 int u=x; 35 int v=g[x][i]; 36 if(d[v]>d[u]+cost[u][v]) 37 { 38 d[v]=d[u]+cost[u][v]; 39 que.push(node{v,d[v]}); 40 } 41 } 42 } 43 } 44 45 void dfs(int x) 46 { 47 if(x==2) 48 { 49 ans++; 50 return ; 51 } 52 for(int i=0;i<g[x].size();i++) 53 { 54 int fx=g[x][i]; 55 if(d[fx]<d[x]) 56 dfs(fx); 57 } 58 } 59 60 int main() 61 { 62 while(scanf("%d",&n),n) 63 { 64 scanf("%d",&m); 65 ans=0; 66 for(int i=1;i<=n;i++) 67 for(int j=1;j<=n;j++) 68 { 69 cost[i][j]=(i==j)?0:INF; 70 } 71 for(int i=0;i<m;i++) 72 { 73 int a,b,c; 74 scanf("%d%d%d",&a,&b,&c); 75 g[a].push_back(b); 76 g[b].push_back(a); 77 cost[a][b]=cost[b][a]=c; 78 } 79 dij(); 80 d[2]=0; 81 dfs(1); 82 printf("%d\n",ans); 83 for(int i=1;i<=n;i++) 84 g[i].clear(); 85 ans=0; 86 } 87 return 0; 88 }
优化分析:存在对某些结点进行了多次dfs,导致时间耗费过多。考虑采用记忆化搜索。我们用sum[i]表示从i出发有多少条到家的路径,对于已知sum[i]的结点i就不需要再次dfs,这样dfs的次数就只有n-1次(n为结点数)。
优化后代码:用时514ms
1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 #include <algorithm> 5 #define INF 0x3f3f3f3f 6 using namespace std; 7 8 const int maxn=1001; 9 vector<int> g[maxn];//图的邻接表表示 10 struct node 11 { 12 int num,dis; 13 }; 14 int n,m; 15 int cost[maxn][maxn],d[maxn]; 16 int sum[maxn]; 17 18 bool operator<(const node& n1,const node& n2)//重载运算符 19 { 20 return n1.dis<n2.dis; 21 } 22 23 void dij() 24 { 25 fill(d+1,d+n+1,INF);//下标从1开始 26 d[2]=0; 27 priority_queue<node> que; 28 que.push(node{2,0}); 29 while(!que.empty()) 30 { 31 int x=que.top().num; 32 que.pop(); 33 for(int i=0;i<g[x].size();i++) 34 { 35 int u=x; 36 int v=g[x][i]; 37 if(d[v]>d[u]+cost[u][v]) 38 { 39 d[v]=d[u]+cost[u][v]; 40 que.push(node{v,d[v]}); 41 } 42 } 43 } 44 } 45 46 void dfs(int x) 47 { 48 for(int i=0;i<g[x].size();i++) 49 { 50 int fx=g[x][i]; 51 if(d[fx]<d[x]) 52 { 53 if(sum[fx]>0) 54 { 55 sum[x]+=sum[fx]; 56 } 57 else 58 { 59 60 61 dfs(fx); 62 sum[x]+=sum[fx]; 63 } 64 } 65 } 66 // return ; 67 } 68 69 int main() 70 { 71 while(scanf("%d",&n),n) 72 { 73 scanf("%d",&m); 74 memset(sum,0,sizeof(sum)); 75 for(int i=1;i<=n;i++) 76 for(int j=1;j<=n;j++) 77 { 78 cost[i][j]=(i==j)?0:INF; 79 } 80 for(int i=0;i<m;i++) 81 { 82 int a,b,c; 83 scanf("%d%d%d",&a,&b,&c); 84 g[a].push_back(b); 85 g[b].push_back(a); 86 cost[a][b]=cost[b][a]=c; 87 } 88 dij(); 89 sum[2]=1; 90 dfs(1); 91 printf("%d\n",sum[1]); 92 for(int i=1;i<=n;i++) 93 g[i].clear(); 94 } 95 return 0; 96 }
此题bug过的地方
(1)fill(d+1,d+1+n,INF),一开始没注意下标是从1开始,写成了fill(d,d+n,INF)。dij函数bug。
(2)每组用例输出后没有清空图,导致下一组用例的图多了许多不属于自己的边和顶点。
hdu_A Walk Through the Forest ——迪杰特斯拉+dfs
标签:push struct span play while code res oca opened
原文地址:http://www.cnblogs.com/onlyli/p/6925532.html