NOIP 2017 d2t2 70points
革命之路漫漫
第一次尝试 40points spfa
1 #include <bits/stdc++.h> 2 #define read read() 3 using namespace std; 4 5 inline int read 6 { 7 int x=0,f=1;char ch=getchar(); 8 while(ch<'0'||ch>'9') {if(ch=='-')f=-1;ch=getchar();} 9 while(ch>='0'&&ch<='9'){x=10*x+(ch-'0');ch=getchar();} 10 return x*f; 11 } 12 13 const int N = 1005; 14 15 struct edge{ 16 int v,nxt,w; 17 }e[N<<1]; 18 19 int n,m; 20 int head[N],size; 21 int dis[N],vis[N],maxn = INT_MAX;23 24 void add(int u,int v,int w) 25 { 26 e[++size].v = v; 27 e[size].w = w; 28 e[size].nxt = head[u]; 29 head[u] = size; 30 } 31 32 queue<int>q; 33 34 void spfa(int s) 35 { 36 memset(dis,0x3f,sizeof(dis)); 37 memset(head,0,sizeof(0)); 38 memset(vis,0,sizeof(vis)); 39 dis[s] = 0; 40 q.push(s); 41 vis[s] = 1; 42 while(!q.empty()) 43 { 44 int u = q.front(); q.pop(); vis[u] = 0; 45 for(int i = head[u]; i ; i = e[i].nxt) 46 { 47 int v = e[i].v, w = e[i].w; 48 if(dis[v] > dis[u] + 1) 49 { 50 dis[v] = dis[u] + 1; 51 if(!vis[v]) 52 { 53 q.push(v); 54 vis[v] = 1; 55 } 56 } 57 } 58 } 59 } 60 61 int main() 62 { 63 freopen("treasure.in","r",stdin); 64 n = read; m = read; 65 int u,v,w; 66 for(int i = 1; i <= m; i++) 67 { 68 u = read; v = read; w = read; 69 add(u,v,w); 70 add(v,u,w);72 } 73 for(int i = 1; i <= n; i++) 74 { 75 spfa(i); 76 int ans = 0; 77 for(int i = 1; i <= n; i++) 78 { 79 ans += dis[i] * w; 80 } 81 maxn = min(maxn , ans); 82 } 83 printf("%d",maxn); 84 return 0; 85 }
第二次尝试 dfs
1 #include <bits/stdc++.h> 2 #define read read() 3 using namespace std; 4 5 const int N = 1005; 6 7 int n,m; 8 int cost[N][N],cnt[N]; 9 int head[N],size; 10 int ans = INT_MAX, mincost;12 13 int read 14 { 15 int x = 0; char ch = getchar(); 16 while(ch < 48 || ch > 57) ch = getchar(); 17 while(ch >= 48&& ch <= 57) { x = 10 * x + ch - 48; ch = getchar();} 18 return x; 19 } 20 21 void dfs(int cur)//暴力枚举所有情况; 22 { 23 if(cur == n) 24 { 25 ans = min(ans,mincost); 26 return; 27 } 28 if(mincost > ans) return; 29 for(int i = 1; i <= n; i++) //枚举出点; 30 { 31 if(!cnt[i]) continue; //还未连通的点不能当作出点; 32 for(int j = 1; j <= n; j++) //枚举入点; 33 { 34 if(i == j || cnt[j] || cost[i][j] == 0x3f3f3f3f) continue; 35 mincost += cnt[i] * cost[i][j]; 36 cnt[j] = cnt[i] + 1; 37 dfs(cur + 1); 38 mincost -= cnt[i] * cost[i][j]; 39 cnt[j] = 0; 40 } 41 } 42 } 43 44 int main() 45 { 46 // freopen("treasure.in","r",stdin); 47 n = read;m = read; 48 memset(cost,0x3f,sizeof(cost)); 49 int u,v; 50 for(int i = 1; i <= m; i++) 51 { 52 u = read; v = read; 53 cost[u][v] = cost[v][u] = min(read , cost[u][v]);56 //细节: u-v之间可能有多条路连接, 忽略其余选最短; 57 } 58 for(int i = 1; i <= n; i++) //枚举起点; 59 { 60 cnt[i] = 1; 61 dfs(1); 62 cnt[i] = 0; 63 } 64 printf("%d",ans); 65 return 0; 66 }