图论

来源:互联网 发布:淘抢火车票软件 编辑:程序博客网 时间:2024/05/01 10:20

内容


/*  * 次小生成树  * 求最小生成树时,用数组Max[i][j]来表示MST中i到j最大边权  * 求完后,直接枚举所有不在MST中的边,替换掉最大边权的边,更新答案  * 点的编号从0开始  */ 上海大学 ACM 模板  by kuangbin     94 / 173  ACM 模板  kuangbin  int pre[MAXN],id[MAXN],visit[MAXN],in[MAXN]; int zhuliu(int root,int n,int m,Edge edge[]) {     int res = 0,u,v;     while(1)     {         for(int i = 0;i < n;i++)             in[i] = INF;         for(int i = 0;i < m;i++)             if(edge[i].u != edge[i].v && edge[i].cost < in[edge[i].v])             {                 pre[edge[i].v] = edge[i].u;                 in[edge[i].v] = edge[i].cost;             }         for(int i = 0;i < n;i++)             if(i != root && in[i] == INF)                 return -1;//不存在最小树形图         int tn = 0;         memset(id,-1,sizeof(id));         memset(visit,-1,sizeof(visit));         in[root] = 0;         for(int i = 0;i < n;i++)         {             res += in[i];             v = i;             while( visit[v] != i && id[v] == -1 && v != root)             {                 visit[v] = i;                 v = pre[v];             }             if( v != root && id[v] == -1 )             {                 for(int u = pre[v]; u != v ;u = pre[u])                     id[u] = tn; 上海大学 ACM 模板  by kuangbin     94 / 173  ACM 模板  kuangbin                  id[v] = tn++;             }         }         if(tn == 0)break;//没有有向环         for(int i = 0;i < n;i++)             if(id[i] == -1)                 id[i] = tn++;         for(int i = 0;i < m;)         {             v = edge[i].v;             edge[i].u = id[edge[i].u];             edge[i].v = id[edge[i].v];             if(edge[i].u != edge[i].v)                 edge[i++].cost -= in[v];             else                 swap(edge[i],edge[--m]);         }         n = tn;         root = id[root];     }     return res; }
</pre><pre name="code" class="cpp">
void addedge(int u,int v,int w){     edges[ecnt++]=Edge(u,v,w);}int zhu_liu(){    int weight=0,i,j,u,v,root=0;    while (1)    {        for(i=0;i<N;i++){            dist[i]=INF;            num[i]=-1;            s[i]=-1;        }        dist[root]=0;        pre[root]=-1;        int cnt=0;        for (i=0;i<ecnt;i++){            Edge e=edges[i];            if (e.u==e.v) continue;            if (dist[e.v]>e.w){                dist[e.v]=e.w;                pre[e.v]=e.u;            }        }        for (i=0;i<N;i++){            if (dist[i]==INF)                return -1;            weight+=dist[i];            u=i;            while (pre[u]!=-1&&s[u]!=i&&num[u]==-1)            {                s[u]=i;                u=pre[u];            }            if (s[u]==i){                while (num[u]==-1){                    num[u]=cnt;                    u=pre[u];                }                cnt++;            }        }        if (cnt==0) return weight;        for (i=0;i<N;i++){            if (num[i]==-1){                num[i]=cnt++;            }        }        for (i=0;i<ecnt;i++){            Edge &e=edges[i];            e.w-=dist[e.v];            e.u=num[e.u];            e.v=num[e.v];        }        root=num[root];        N=cnt;    }    return weight;}
#include<cstring>#include<cstdlib>#include<cstdio>#include<vector>#include<string>#include<iostream>#include<algorithm>#include<stack>using namespace std;#define MAXM 10010#define MAX 40struct Edge{    int v,num;    Edge(){}    Edge(int x,int y)    {        this->v=x;        this->num=y;    }};string s[MAXM];int n,in[MAX],out[MAX];int mark[MAXM],E[MAXM],U[MAXM];vector<Edge>G[MAX];int parent[MAX],vis[MAX];bool cmp(string a,string b){    return a<b;}int find(int x){    if (parent[x]>=0)    {        return parent[x]=find(parent[x]);    }    return x;}int check(){    int i,cnt=0,cntx=0,cnty=0,start=-1;;    for (i=0;i<26;i++)    {        if (vis[i])        {            if (start==-1)                start=i;            if (parent[i]==-1)            {//                cout<<"cnt"<<endl;                cnt++;                if (cnt>1)                    return -1;            }            if (in[i]-out[i]==-1)            {                start=i;                cntx++;            }            else if (in[i]-out[i]==1)            {                cnty++;            }            else if (abs(in[i]-out[i])>1)            {//                cout<<"xxxx"<<endl;                return -1;            }        }        if (cntx>1||cnty>1)        {            return -1;        }    }    return start;}int main(){    int T;//    ios::sync_with_stdio(false);//    freopen()    cin>>T;    while (T--)    {        cin>>n;        int i,j,u,v,flag,L;        memset(in,0,sizeof(in));        memset(out,0,sizeof(out));        memset(mark,0,sizeof(mark));        memset(parent,-1,sizeof(parent));        memset(vis,0,sizeof(vis));        for (i=0;i<26;i++)        {            G[i].clear();        }        for (i=0;i<n;i++)        {            cin>>s[i];        }        sort(s,s+n,cmp);        for (i=0;i<n;i++)        {//            cout<<s[i]<<endl;            u=s[i][0]-'a';            L=s[i].size();            v=s[i][L-1]-'a';            U[i]=v;            G[u].push_back(Edge(v,i));            in[v]++,out[u]++;            vis[u]=vis[v]=1;            u=find(u);            v=find(v);            if (u!=v)            {                parent[u]=v;            }        }        flag=check();        if (flag<0)        {            cout<<"***"<<endl;        }        else        {            int cnt=0;            stack<int>S;            for (i=0;i<G[flag].size();i++)            {                Edge e=G[flag][i];                if (!mark[e.num])                {                    mark[e.num]=1;                    S.push(e.num);                    break;                }            }            while (!S.empty())            {                flag=0;                int temp=S.top();                u=U[temp];                for (i=0;i<G[u].size();i++)                {                    Edge e=G[u][i];                    if (!mark[e.num])                    {                        mark[e.num]=1;                        S.push(e.num);                        flag=1;                        break;                    }                }                if (!flag)                {//                    cout<<S.top()<<endl;                    E[cnt++]=S.top();                    S.pop();                }            }            for (i=cnt-1;i>=0;i--)            {                cout<<s[E[i]];                if (i!=0)                {                    cout<<".";                }            }            cout<<endl;        }    }    return 0;}


0 0
原创粉丝点击