ifrog 1130 喵哈哈村的魔法大师╳灬兲笙疯癫°月 缩点+最小路径覆盖+背包

来源:互联网 发布:淘宝李宁是假的吗 编辑:程序博客网 时间:2024/05/22 15:10

题目链接点这里

题意应该很清楚。。

wa了无数发,,居然没察觉最小路径覆盖不能有环,,,会出错,,(捂脸

然后,,就是先缩点,,然后floyd传递闭包(害怕超时的同学,,可以bitset压缩然后floyd,复杂度是n^3/32,就是我下面写的),然后建图跑网络流,,最后来一个01背包。。

不过01背包里面有个小技巧,,一般这道题的的背包做法,复制度是n^3,虽然不会超时,也很耗时间。。

是这么写的:sum是总的次数

mem(dp,0x3f);        dp[0]=0;        for(int i=1; i<=k; i++)            for(int j=sum; j>=val[i]; j--)                dp[j]=min(dp[j],dp[j-val[i]]+cost[i]);        int minn=INF;        for(int i=w; i<=sum; i++)            minn=min(minn,dp[i]);     cout<<(minn==INF?-1:minn)<<endl;

然后我看了卿学姐的代码。。

他是这么写的。。

mem(dp,0x3f);        dp[0]=0;        for(int i=1; i<=k; i++)            for(int j=w; j>=0; j--)                if(val[i]>j) dp[j]=min(dp[j],cost[i]);                else dp[j]=min(dp[j],dp[j-val[i]]+cost[i]);
n^2很厉害有没有
#include<iostream>#include<cstdio>#include<math.h>#include<algorithm>#include<map>#include<set>#include<bitset>#include<stack>#include<queue>#include<string.h>#include<cstring>#include<vector>#include<time.h>#include<stdlib.h>using namespace std;#define INF 0x3f3f3f3f#define INFLL 0x3f3f3f3f3f3f3f3f#define FIN freopen("input.txt","r",stdin);#define mem(x,y) memset(x,y,sizeof(x));typedef unsigned long long ULL;typedef long long LL;#define fuck(x) cout<<x<<endl;#define MX 555#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1typedef pair<pair<int,int>,int> PIII;typedef pair<int,int> PII;int n,m,k;int S,T;int head[2*MX],cnt;struct Edge{    int to,nxt,cap;} E[MX*MX*2];void edge_init(){    mem(head,-1);    cnt=0;}void edge_add(int u,int v,int cap){    E[cnt].nxt=head[u];    E[cnt].to=v;    E[cnt].cap=cap;    head[u]=cnt++;}bool vis[2*MX];int d[2*MX],cur[2*MX];bool BFS(int s,int t){    mem(vis,0);    queue<int> Q;    Q.push(s);    vis[s]=1;    d[s]=0;    d[t]=-1;    while(!Q.empty())    {        int u=Q.front();        Q.pop();        for(int i=head[u]; ~i; i=E[i].nxt)        {            int v=E[i].to;            if(vis[v]||!E[i].cap) continue;            d[v]=d[u]+1;            vis[v]=1;            Q.push(v);        }    }    return d[t]!=-1;}int DFS(int x,int t,int a){    if(x==t||a==0) return a;    int flow=0,f;    for(int &i=cur[x]; ~i; i=E[i].nxt)    {        int v=E[i].to;        if(d[v]==d[x]+1&&(f=DFS(v,t,min(a,E[i].cap))))        {            E[i].cap-=f;            E[i^1].cap+=f;            flow+=f;            a-=f;            if(a==0) break;        }    }    return flow;}int Dinic(int s,int t){    int flow=0;    while(BFS(s,t))    {        memcpy(cur,head,sizeof(head));        flow+=DFS(s,t,INF);    }    return flow;}int low[MX],pre[MX],sccno[MX],dfs_block,scc_cnt;stack<int> SS;void dfs(int u){    low[u]=pre[u]=++dfs_block;    SS.push(u);    for(int i=head[u]; ~i; i=E[i].nxt)    {        int v=E[i].to;        if(!pre[v])        {            dfs(v);            low[u]=min(low[u],low[v]);        }        else if(!sccno[v])        {            low[u]=min(low[u],pre[v]);        }    }    if(pre[u]==low[u])    {        scc_cnt++;        while(1)        {            int w=SS.top();            SS.pop();            sccno[w]=scc_cnt;            if(w==u) break;        }    }}void find_scc(){    dfs_block=scc_cnt=0;    mem(pre,0);    mem(low,0);    mem(sccno,0);    for(int i=1; i<=n; i++)        if(!pre[i]) dfs(i);}bitset<MX> G[MX];int val[MX],cost[MX];int dp[MX];int main(){    FIN    int cas;    cin>>cas;    while(cas--)    {        edge_init();        scanf("%d%d%d",&n,&m,&k);        for(int i=1; i<=m; i++)        {            int u,v;            scanf("%d%d",&u,&v);            edge_add(u,v,0);        }        find_scc();//缩点        for(int i=1; i<=scc_cnt; i++)G[i].reset();        for(int i=1; i<=n; i++)        {            for(int j=head[i]; ~j; j=E[j].nxt)            {                int v=E[j].to;                G[sccno[i]][sccno[v]]=1;            }        }        edge_init();        S=0;        T=2*scc_cnt+1;        for(int i=1; i<=scc_cnt; i++)        {            edge_add(S,i,1);            edge_add(i,S,0);            edge_add(i+scc_cnt,T,1);            edge_add(T,i+scc_cnt,0);        }        for(int k=1; k<=scc_cnt; k++)            for(int i=1; i<=scc_cnt; i++) if(G[i][k])G[i]|=G[k];        for(int i=1; i<=scc_cnt; i++)            for(int j=1; j<=scc_cnt; j++)if(i!=j&&G[i][j])                {                    edge_add(i,j+scc_cnt,INF);                    edge_add(j+scc_cnt,i,0);                }        for(int i=1; i<=k; i++)scanf("%d%d",&cost[i],&val[i]);        int w=scc_cnt-Dinic(S,T);        mem(dp,0x3f);        dp[0]=0;        for(int i=1; i<=k; i++)            for(int j=w; j>=0; j--)                if(val[i]>j) dp[j]=min(dp[j],cost[i]);                else dp[j]=min(dp[j],dp[j-val[i]]+cost[i]);        cout<<(dp[w]==INF?-1:dp[w])<<endl;    }    return 0;}



阅读全文
0 0
原创粉丝点击