zoukankan      html  css  js  c++  java
  • 单身三连之二

    一道正解不可靠,暴力碾标算的题。

    题目大意:

      有一张无向图,求经过起点的最小环。(点数N<=1×104,边数M<=4×104,多测,无解输出-1)

    题解:

      先判断图的合法性。从起点开始dfs,判断能否从其他路径回到起点,若搜索失败,则一定无解。

      已知图是合法的,我们可以将连接起点的边断掉,对每个起点连接的点跑一遍Dijkstra,求出两点间的最短路径,然后枚举更新,用两个不同的和起点相连的点去更新答案。

      注意细节处理和赋极大值,多测要清空。

      理论复杂度O(N2logM),不过由于和起点相连的点较少,复杂度远远达不到上界。如果遇到菊花图,则Dijkstra表现会非常优秀,不易被卡掉。

      此题用spfa或A*也可做。spfa用法和Dijkstra相似。A*搜索时要注意不能沿已走过的边回去,剪枝就行,实际复杂度最低,不过码量较大。

    Code:

     

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<queue>
      4 #include<cstring>
      5 using namespace std;
      6 const int N=10010;
      7 const int M=40010;
      8 const int inf=99999999;
      9 int t,n,m,nm=1;
     10 int fi[N],in[N],d[N],de[N];
     11 bool vis[N],v[N];
     12 struct edge{
     13     int u,v,l,ne;
     14 }e[M<<1];
     15 struct point{
     16     int id,d;
     17     friend bool operator < (const point a1,const point a2)
     18     {
     19         return a1.d>a2.d;
     20     }
     21 }p[N];
     22 priority_queue<point> q;
     23 void add(int x,int y,int z)
     24 {
     25     e[++nm].u=x;
     26     e[nm].v=y;
     27     e[nm].l=z;
     28     e[nm].ne=fi[x];
     29     fi[x]=nm;
     30 }
     31 int read()
     32 {
     33     int s=0;
     34     char c=getchar();
     35     while(c<'0'||c>'9')    c=getchar();
     36     while(c>='0'&&c<='9'){
     37         s=(s<<3)+(s<<1)+c-'0';
     38         c=getchar();
     39     }
     40     return s;
     41 }
     42 void clean()
     43 {
     44     memset(fi,0,sizeof(fi));    
     45     memset(in,0,sizeof(in));
     46     memset(vis,false,sizeof(vis));
     47     memset(v,false,sizeof(v));
     48     memset(d,0,sizeof(d));
     49     for(int i=1;i<=10000;i++)    de[i]=inf;
     50     nm=1;
     51 }
     52 bool dfs(int x,int p)
     53 {
     54     vis[x]=true;
     55     for(int i=fi[x];i!=0;i=e[i].ne){
     56         int y=e[i].v;
     57         if(y==1&&p!=1)    return true;
     58         if(vis[y])    continue;
     59         if(dfs(y,x))    return true;
     60     }
     61     return false;
     62 }
     63 void Dij(int now)
     64 {
     65     for(int i=1;i<=n;i++){
     66         p[i].d=inf;
     67         v[i]=false;
     68     }
     69     p[now].d=0;
     70     q.push(p[now]);
     71     while(!q.empty()){
     72         point x=q.top();q.pop();
     73         if(v[x.id])
     74             continue;
     75         v[x.id]=true;
     76         for(int i=fi[x.id];i!=0;i=e[i].ne){
     77             int y=e[i].v;
     78             if(y==1)    continue;
     79             if(p[y].d>x.d+e[i].l){
     80                 p[y].d=x.d+e[i].l;
     81                 q.push(p[y]);
     82             }
     83         }
     84     }
     85     for(int i=2;i<=n;i++)
     86         if(i!=now)    de[i]=min(de[i],d[now]+p[i].d);
     87 }
     88 int main()
     89 {
     90     t=read();
     91     while(t--)
     92     {
     93         clean();n=read();m=read();
     94         for(int i=1;i<=m;i++){
     95             int x=read(),y=read(),z=read();
     96             in[x]++;in[y]++;add(x,y,z);add(y,x,z);
     97         }
     98         if(!dfs(1,0)){
     99             printf("-1
    ");
    100             continue;
    101         }
    102         for(int i=1;i<=n;i++){
    103             d[i]=inf;
    104             p[i].id=i;
    105         }
    106         for(int i=fi[1];i!=0;i=e[i].ne){
    107             int y=e[i].v;
    108             d[y]=e[i].l;
    109             Dij(y);
    110         }
    111         int ans=inf;
    112         for(int i=2;i<=n;i++)    ans=min(ans,d[i]+de[i]);
    113         printf("%d
    ",ans);
    114     }
    115     return 0;
    116 }
    View Code

     

  • 相关阅读:
    邮箱的第99封邮件,第1个Offer
    学校的多媒体网站也模仿Google改版了
    惠普:计算机在非洲大有可为(zz)
    PPLive是不错的东东
    Google增加反病毒功能
    开复给中国学生的第五封信 – 你有选择的权利(zz)
    Yahoo中国变脸?
    拟停止本Blog更新
    在FC4上装GT4.0
    Google CodeJam 中国编程挑战赛拉开帷幕
  • 原文地址:https://www.cnblogs.com/hz-Rockstar/p/11220112.html
Copyright © 2011-2022 走看看