【模拟7.19】那一天她离我而去(最短路,估价函数剪枝)
这题忘记输出-1,wa0了QAQ
首先这题我先看的第二题数据范围,n==m意味着只有一个环,所以可以用tarjan的算法
把环判出来,比较简单。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<algorithm> 6 #include<cmath> 7 #include<stack> 8 #include<vector> 9 #define ll long long 10 using namespace std; 11 #define MAXN 80010 12 #define ps push_back 13 struct node{int to,n,w;}e[MAXN];int tot=0;int head[MAXN]; 14 void add(int u,int v,int w){e[++tot].to=v;e[tot].n=head[u];e[tot].w=w;head[u]=tot;} 15 int vis[MAXN],low[MAXN],dfn[MAXN]; 16 vector<int>sum[MAXN];int de=0; 17 int belong[MAXN]; 18 int n,m;int fa[MAXN]; 19 stack<int>q;int cnt=0;int ans_w=10000000; 20 void tarjan(int x,int w) 21 { 22 low[x]=dfn[x]=++de;vis[x]=1;q.push(x); 23 for(int i=head[x];i;i=e[i].n) 24 { 25 int to=e[i].to; 26 if(dfn[to]==0) 27 { 28 fa[to]=x; 29 tarjan(to,w+e[i].w); 30 low[x]=min(low[x],low[to]); 31 } 32 else if(vis[to]&&fa[x]!=to) 33 { 34 if(to==1) 35 { 36 ans_w=min(ans_w,w+e[i].w); 37 } 38 low[x]=min(low[x],dfn[to]); 39 } 40 } 41 if(dfn[x]==low[x]) 42 { 43 int top=0; 44 cnt++; 45 do 46 { 47 top=q.top();q.pop();vis[top]=0; 48 sum[cnt].ps(top); 49 belong[top]=cnt; 50 } 51 while(x!=top); 52 } 53 } 54 int T; 55 int main() 56 { 57 scanf("%d",&T); 58 while(T--) 59 { 60 ans_w=100000000; 61 memset(head,0,sizeof(head));tot=0; 62 memset(vis,0,sizeof(vis)); 63 memset(low,0,sizeof(low)); 64 memset(dfn,0,sizeof(dfn)); 65 scanf("%d%d",&n,&m); 66 for(int i=1;i<=m;++i) 67 { 68 int x,y,w; 69 scanf("%d%d%d",&x,&y,&w); 70 add(x,y,w);add(y,x,w); 71 } 72 tarjan(1,0); 73 for(int x=1;x<=cnt;++x) 74 { 75 for(int i=0;i<sum[x].size();++i) 76 { 77 int to=sum[x][i]; 78 } 79 } 80 if(ans_w==100000000)printf("-1\n"); 81 else printf("%d\n",ans_w); 82 for(int i=1;i<=cnt;++i)sum[i].clear(); 83 cnt=0; 84 } 85 }
满分的话听了skyh大佬的讲评后用估价函数剪枝DFS,然后暴力跑
注意DFS中标记的是边而不是点(想起来tarjan的割桥)
因为他点可以重复经过,边不能
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<algorithm> 6 #include<cmath> 7 #include<stack> 8 #include<vector> 9 #include<queue> 10 #define MAXN 41010 11 #define ps push_back 12 #define ll int 13 using namespace std; 14 struct node{ll to,n,w;}e[2*MAXN]; 15 ll tot=0;ll head[MAXN]; 16 void add(ll u,ll v,ll w){e[++tot].to=v;e[tot].n=head[u];e[tot].w=w;head[u]=tot;} 17 bool bian[2*MAXN]; 18 ll dis[MAXN]; 19 priority_queue< pair<ll,ll> >q; 20 ll ans_w=0; 21 ll n,m; 22 void SPFA(ll top) 23 { 24 memset(bian,0,sizeof(bian)); 25 dis[top]=0;q.push(make_pair(0,top));bian[top]=1; 26 while(!q.empty()) 27 { 28 ll x=q.top().second;q.pop(); 29 for(ll i=head[x];i;i=e[i].n) 30 { 31 ll to=e[i].to; 32 if(dis[to]>dis[x]+e[i].w) 33 { 34 dis[to]=dis[x]+e[i].w; 35 if(bian[to]==0) 36 { 37 q.push(make_pair(-dis[to],to)); 38 bian[to]=1; 39 } 40 } 41 } 42 } 43 } 44 void DFS(ll x,ll w) 45 { 46 if(w+dis[x]>=ans_w)return ; 47 if(x==1) 48 { 49 if(w!=0) 50 { 51 ans_w=min(ans_w,w); 52 return ; 53 } 54 } 55 for(ll i=head[x];i;i=e[i].n) 56 { 57 ll to=e[i].to; 58 if(bian[i]==1)continue; 59 bian[i]=1;bian[(i^1)]=1; 60 DFS(to,w+e[i].w); 61 bian[i]=0;bian[(i^1)]=0; 62 } 63 } 64 ll T; 65 int main() 66 { 67 scanf("%d",&T); 68 while(T--) 69 { 70 ans_w=0x7ffffff;tot=1; 71 memset(head,0,sizeof(head)); 72 memset(dis,0x7f,sizeof(dis)); 73 scanf("%d%d",&n,&m); 74 for(ll i=1;i<=m;++i) 75 { 76 ll x,y,w; 77 scanf("%d%d%d",&x,&y,&w); 78 add(x,y,w);add(y,x,w); 79 } 80 SPFA(1); 81 memset(bian,0,sizeof(bian)); 82 DFS(1,0); 83 if(ans_w==0x7ffffff) 84 printf("-1\n"); 85 else 86 printf("%d\n",ans_w); 87 } 88 }