HDU 1827(强连通+缩点 判入度)
请教了月光大牛和DK大牛 具体思路是首先提取强连通分量 然后将分量缩点重新构图 记录各点入度 将入度为0的点所代表的分量中的费用最小值记录下来 相加得到最小费用 其入度为0点的个数就是要求的通知的人数
具体代码如下 使用Tarjan寻找强连通 顺便ORZ两位大牛
#include <iostream>
#include <stack>
#include <queue>
using namespace std;
typedef struct
{
long v,next;
}Edge;
typedef struct
{
long Num;
long Used;
long Alive;
long Low;
long belong;
void init(long pos)
{
Num=Used=Alive=Low=0;
belong=pos;
}
}Node;
const long MAXN=2100;
long N,M;//点,边
Edge e[MAXN];//边数组
long p[MAXN>>1];//辅助数组
long In[MAXN>>1];
Node vec[MAXN>>1];//点
stack<long> s;
long Permit;//时间戳
typedef struct
{
long id;
long cost;
}Man;
priority_queue<Man> q;
bool hash[MAXN>>1];
inline bool operator <(const Man a,const Man b)
{
return a.cost>b.cost;
}
inline void init()
{
long i;
while (!s.empty())
{
s.pop();
}
while (!q.empty())
{
q.pop();
}
Permit=0;
memset(hash,0,sizeof(hash));
memset(p,-1,sizeof(p));
memset(In,0,sizeof(In));
for (i=0;i<=N;++i)
{
vec[i].init(i);
}
for (i=1;i<=N;++i)
{
Man tt;
scanf("%ld",&tt.cost);
tt.id=i;
q.push(tt);
}
for (i=0;i<M;++i)
{
long from,to;
scanf("%ld %ld",&from,&to);
e[i].next=p[from];
e[i].v=to;
p[from]=i;
}
}
inline void update(long &a,long b)
{
if(a>b) a=b;
}
inline void dfs(long pos)
{
s.push(pos);
vec[pos].Low=vec[pos].Num=++Permit;
vec[pos].Used=vec[pos].Alive=true;
long j;
for (j=p[pos];j!=-1;j=e[j].next)
{
long to=e[j].v;
if (vec[to].Used)
{
if (vec[to].Alive)
{
update(vec[pos].Low,vec[to].Num);
}
}
else
{
dfs(to);
update(vec[pos].Low,vec[to].Low);
}
}
if (vec[pos].Num==vec[pos].Low)
{
long t;
while ((t=s.top())!=pos)
{
vec[t].belong=pos;
vec[t].Alive=false;
s.pop();
}
vec[pos].belong=pos;
vec[pos].Alive=false;
s.pop();
}
}
inline void Tarjan()
{
long i;
for (i=1;i<=N;++i)
{
if (!vec[i].Used)
{
dfs(i);
}
}
}
int main()
{
while (scanf("%ld %ld",&N,&M)!=EOF)
{
init();
Tarjan();
long i,j;
for (i=1;i<=N;++i)
{
for (j=p[i];j!=-1;j=e[j].next)
{
long from=vec[i].belong;
long to=vec[e[j].v].belong;
if(from!=to)
{
++In[to];
}
}
}
long cost=0,ct=0;
while (!q.empty())
{
Man t=q.top();
q.pop();
long father=vec[t.id].belong;
if (In[father]!=0||hash[father])
{
continue;
}
else
{
++ct;
cost+=t.cost;
hash[father]=true;
++In[father];
}
}
printf("%ld %ld\n",ct,cost);
}
return 0;
}
#include <stack>
#include <queue>
using namespace std;
typedef struct
{
long v,next;
}Edge;
typedef struct
{
long Num;
long Used;
long Alive;
long Low;
long belong;
void init(long pos)
{
Num=Used=Alive=Low=0;
belong=pos;
}
}Node;
const long MAXN=2100;
long N,M;//点,边
Edge e[MAXN];//边数组
long p[MAXN>>1];//辅助数组
long In[MAXN>>1];
Node vec[MAXN>>1];//点
stack<long> s;
long Permit;//时间戳
typedef struct
{
long id;
long cost;
}Man;
priority_queue<Man> q;
bool hash[MAXN>>1];
inline bool operator <(const Man a,const Man b)
{
return a.cost>b.cost;
}
inline void init()
{
long i;
while (!s.empty())
{
s.pop();
}
while (!q.empty())
{
q.pop();
}
Permit=0;
memset(hash,0,sizeof(hash));
memset(p,-1,sizeof(p));
memset(In,0,sizeof(In));
for (i=0;i<=N;++i)
{
vec[i].init(i);
}
for (i=1;i<=N;++i)
{
Man tt;
scanf("%ld",&tt.cost);
tt.id=i;
q.push(tt);
}
for (i=0;i<M;++i)
{
long from,to;
scanf("%ld %ld",&from,&to);
e[i].next=p[from];
e[i].v=to;
p[from]=i;
}
}
inline void update(long &a,long b)
{
if(a>b) a=b;
}
inline void dfs(long pos)
{
s.push(pos);
vec[pos].Low=vec[pos].Num=++Permit;
vec[pos].Used=vec[pos].Alive=true;
long j;
for (j=p[pos];j!=-1;j=e[j].next)
{
long to=e[j].v;
if (vec[to].Used)
{
if (vec[to].Alive)
{
update(vec[pos].Low,vec[to].Num);
}
}
else
{
dfs(to);
update(vec[pos].Low,vec[to].Low);
}
}
if (vec[pos].Num==vec[pos].Low)
{
long t;
while ((t=s.top())!=pos)
{
vec[t].belong=pos;
vec[t].Alive=false;
s.pop();
}
vec[pos].belong=pos;
vec[pos].Alive=false;
s.pop();
}
}
inline void Tarjan()
{
long i;
for (i=1;i<=N;++i)
{
if (!vec[i].Used)
{
dfs(i);
}
}
}
int main()
{
while (scanf("%ld %ld",&N,&M)!=EOF)
{
init();
Tarjan();
long i,j;
for (i=1;i<=N;++i)
{
for (j=p[i];j!=-1;j=e[j].next)
{
long from=vec[i].belong;
long to=vec[e[j].v].belong;
if(from!=to)
{
++In[to];
}
}
}
long cost=0,ct=0;
while (!q.empty())
{
Man t=q.top();
q.pop();
long father=vec[t.id].belong;
if (In[father]!=0||hash[father])
{
continue;
}
else
{
++ct;
cost+=t.cost;
hash[father]=true;
++In[father];
}
}
printf("%ld %ld\n",ct,cost);
}
return 0;
}