hdu 6165 FFF at Valentine (数学思想 || 缩点)

来源:互联网 发布:gvim windows 编辑:程序博客网 时间:2024/06/06 11:27

数学思想做这个题,就有点套路了。这个题目要求的是什么的呢?一个点能到其他所有的点。如果这样的以下条件肯定会成立,假设点1 2 3 4 5;

1是根节点,有一条路径1->2->3->4->5;

所以1 2 3 4 5 .                1代表的是有路径,0代表没有路径,如果1->2有路径,把(1,2)(2,1)都标记了                 

    1 1 1 1 1 1                    这个图肯定全为1.对每个点进行深搜,最坏的情况是,所有的点成为一个大的环

    2 0 1 1 1 1                   如果120组数据全都是这种情况,会超时3-6秒,但是不存在的,1800ms过了

    3 0 0 1 1 1

    4 0 0 0 1 1

    5 0 0 0 0 1

#include<bits/stdc++.h>using namespace std;#define  pb push_backvector <int>g[1005];bool flag[1005][1005];bool vis[1005];int cnt,n;void dfs(int u){    for(int j=0;j<g[u].size();j++)    {        int v=g[u][j];        flag[cnt][v]=1;        flag[v][cnt]=1;        if(!vis[v])        {            vis[v]=1;            dfs(v);        }    }}void solve(){    for(int i=1;i<=n;i++)    {    memset(vis,0,sizeof(vis));       cnt=i;       vis[i]=1;       dfs(i);       flag[i][i]=1;    }}int main(){ //freopen("in.txt","r",stdin); //  freopen("out.txt","w",stdout); int t; scanf("%d",&t); while(t--) {     int m,a,b;     memset(flag,0,sizeof(flag));     scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++)g[i].clear();     for(int i=1;i<=m;i++)     {         scanf("%d%d",&a,&b);         g[a].pb(b);     }     solve();     int ans=1;     for(int i=1;i<=n;i++)        {for(int j=1;j<=n;j++)         {//cout<<flag[i][j]<<" ";        if(!flag[i][j])ans=0;        }        //cout<<endl;        }        if(ans)printf("I love you my love and our love save us!\n");        else puts("Light my fire!"); }    return 0;}

强联通分量

#include<bits/stdc++.h>using namespace std;#define  pb push_backconst int maxn=1100;int V;              //顶点数vector<int>G[maxn]; //图的邻接表表示vector<int>rG[maxn];//把边反向后的图vector<int>vs;      //后序遍历顺序的顶点列表bool used[maxn];   //访问标记int cmp[maxn];     //所属强连通分量的拓扑序int in[maxn];vector<int>g[maxn];queue<int >q;void init(){    for(int i=0; i<maxn; i++)        G[i].clear(),rG[i].clear(),g[i].clear();    while(!q.empty())q.pop();}void add_edge(int from,int to){    G[from].pb(to);    rG[to].pb(from);}void dfs(int u){    used[u]=true;    for(int i=0; i<(int)G[u].size(); i++)    {        if(!used[G[u][i]])dfs(G[u][i]);    }    vs.push_back(u);}void rdfs(int u,int k){    used[u]=true;    cmp[u]=k;    for(int i=0; i<(int)rG[u].size(); i++)    {        if(!used[rG[u][i]])rdfs(rG[u][i],k);    }}int scc(){    memset(used,0,sizeof(used));    vs.clear();    for(int v=1; v<=V; v++)        if(!used[v])dfs(v);    memset(used,0,sizeof(used));    int k=0;    for(int i=vs.size()-1; i>=0; i--)    {        if(!used[vs[i]])rdfs(vs[i],k++);    }    //以上为强联通分量模板,in数组处理缩点    memset(in,0,sizeof(in));    for(int i=1; i<=V; i++)        for(int j=0; j<(int)G[i].size(); j++)        {            int v=G[i][j];          //  cout<<v<<endl;            if(cmp[i]!=cmp[v])            {                in[cmp[v]]++;                g[cmp[i]].pb(cmp[v]);            }        }    return k;}int main(){//freopen("in.txt","r",stdin);//  freopen("out.txt","w",stdout);//ios::sync_with_stdio(false);    int t;    scanf("%d",&t);    while(t--)    {        init();        int m,a,b;        scanf("%d%d",&V,&m);        for(int i=1; i<=m; i++)        {            scanf("%d%d",&a,&b);            add_edge(a,b);        }        int k=scc();        int flag=0;        for(int i=0; i<k; i++)        {            if(in[i]==0)flag++,q.push(i);            if(flag==2)break;        }        if(flag<2)        {            while(!q.empty())            {                int p=q.front();                q.pop();                flag=0;                for(int i=0; i<(int)g[p].size(); i++)                {                    int v=g[p][i];                    in[v]--;                    if(in[v]==0)flag++,q.push(v);                }                if(flag>=2)break;            }        }        if(flag<2) puts("I love you my love and our love save us!");        else  puts("Light my fire!");    }    return 0;}


原创粉丝点击